jdnssec-tools/src/main/java/com/verisignlabs/dnssec/security/ProtoNSEC3.java

231 lines
6.1 KiB
Java

/*
* Copyright (c) 2005, 2022 Verisign. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. The name of the author may not
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.verisignlabs.dnssec.security;
import org.xbill.DNS.DClass;
import org.xbill.DNS.NSEC3Record;
import org.xbill.DNS.Name;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.utils.base16;
import org.xbill.DNS.utils.base32;
/**
* This is a class representing a "prototype NSEC3" resource record. These are
* used as an intermediate stage (in zone signing) between determining the list
* of NSEC3 records and forming them into a viable chain.
*
* @author David Blacka
*/
public class ProtoNSEC3 {
private Name originalOwner;
private int hashAlg;
private byte flags;
private int iterations;
private byte[] salt;
private byte[] next;
private byte[] owner; // cached numerical owner value.
private TypeMap typemap;
private Name zone;
private Name name;
private int dclass;
private long ttl;
private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, false);
/**
* Creates an NSEC3 Record from the given data.
*/
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
int hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
TypeMap typemap) {
this.zone = zone;
this.owner = owner;
this.dclass = dclass;
this.ttl = ttl;
this.hashAlg = hashAlg;
this.flags = flags;
this.iterations = iterations;
this.salt = salt;
this.next = next;
this.typemap = typemap;
this.originalOwner = originalOwner;
}
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
int hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
int[] types) {
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations, salt, next,
TypeMap.fromTypes(types));
}
private String hashToString(byte[] hash) {
if (hash == null)
return null;
return b32.toString(hash);
}
public Name getName() {
if (name == null) {
try {
name = new Name(hashToString(owner), zone);
} catch (TextParseException e) {
// This isn't going to happen.
}
}
return name;
}
public Name getOriginalOwnerName() {
return this.originalOwner;
}
public byte[] getNext() {
return next;
}
public void setNext(byte[] next) {
this.next = next;
}
public byte getFlags() {
return flags;
}
public boolean getOptOutFlag() {
return (flags & NSEC3Record.Flags.OPT_OUT) != 0;
}
public void setOptOutFlag(boolean optOutFlag) {
if (optOutFlag)
this.flags |= NSEC3Record.Flags.OPT_OUT;
else
this.flags &= ~NSEC3Record.Flags.OPT_OUT;
}
public long getTTL() {
return ttl;
}
public void setTTL(long ttl) {
this.ttl = ttl;
}
public TypeMap getTypemap() {
return typemap;
}
public int[] getTypes() {
return typemap.getTypes();
}
public void setTypemap(TypeMap typemap) {
this.typemap = typemap;
}
public int getDClass() {
return dclass;
}
public int getHashAlgorithm() {
return hashAlg;
}
public int getIterations() {
return iterations;
}
public byte[] getOwner() {
return owner;
}
public byte[] getSalt() {
return salt;
}
public Name getZone() {
return zone;
}
public NSEC3Record getNSEC3Record() {
return new NSEC3Record(getName(), dclass, ttl, hashAlg, flags, iterations, salt, next, getTypes());
}
public void mergeTypes(TypeMap newTypes) {
int[] nt = newTypes.getTypes();
for (int i = 0; i < nt.length; i++) {
if (!typemap.get(nt[i]))
typemap.set(nt[i]);
}
}
public int compareTo(ProtoNSEC3 o) {
if (o == null)
return 1;
byte[] origOwner = o.getOwner();
int len = owner.length < origOwner.length ? origOwner.length : owner.length;
for (int i = 0; i < len; i++) {
int d = ((owner[i] & 0xFF) - (origOwner[i] & 0xFF));
if (d != 0)
return d;
}
return owner.length - origOwner.length;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getName());
sb.append(' ');
sb.append(ttl);
sb.append(' ');
sb.append(DClass.string(dclass));
sb.append(" NSEC3 ");
sb.append(flags);
sb.append(' ');
sb.append(hashAlg);
sb.append(' ');
sb.append(iterations);
sb.append(' ');
sb.append(salt == null ? "-" : base16.toString(salt));
sb.append(' ');
String nextstr = (next == null) ? "(null)" : b32.toString(next);
sb.append(nextstr);
sb.append(' ');
sb.append(typemap.toString());
return sb.toString();
}
public static class Comparator implements java.util.Comparator<ProtoNSEC3> {
public int compare(ProtoNSEC3 a, ProtoNSEC3 b) {
return a.compareTo(b);
}
}
}