// Copyright (c) 1999 Brian Wellington (bwelling@xbill.org)
// Portions Copyright (c) 1999 Network Associates, Inc.

package org.xbill.DNS;

import java.util.*;

import org.xbill.DNS.utils.*;

/**
 * Constants and functions relating to DNSSEC (algorithm constants).
 * DNSSEC provides authentication for DNS information.  RRsets are
 * signed by an appropriate key, and a SIG record is added to the set.
 * A KEY record is obtained from DNS and used to validate the signature,
 * The KEY record must also be validated or implicitly trusted - to
 * validate a key requires a series of validations leading to a trusted
 * key.  The key must also be authorized to sign the data.
 * @see SIGRecord
 * @see KEYRecord
 * @see RRset
 *
 * @author Brian Wellington
 */

public class DNSSEC {

private
DNSSEC() { }

public static final byte RSAMD5 = 1;
public static final byte RSA = RSAMD5;
public static final byte DH = 2;
public static final byte DSA = 3;
public static final byte RSASHA1 = 5;

public static final byte Failed = -1;
public static final byte Insecure = 0;
public static final byte Secure = 1;

/* 
 * Creates an array containing fields of the SIG record and the RRsets to
 * be signed.  The output of this should be cryptographically signed or
 * verified.
 */
public static byte []
digestRRset(SIGRecord sig, RRset rrset) {
	DataByteOutputStream out = new DataByteOutputStream();

	out.writeShort(sig.getTypeCovered());
	out.writeByte(sig.getAlgorithm());
	out.writeByte(sig.getLabels());
	out.writeInt(sig.getOrigTTL());
	out.writeInt((int) (sig.getExpire().getTime() / 1000));
	out.writeInt((int) (sig.getTimeSigned().getTime() / 1000));
	out.writeShort(sig.getFootprint());
	sig.getSigner().toWireCanonical(out);

	int size = rrset.size();
	byte [][] records = new byte[size][];

	Iterator it = rrset.rrs();
	Name name = rrset.getName();
	Name wild = null;
	if (name.labels() > sig.getLabels())
		wild = name.wild(name.labels() - sig.getLabels());
	while (it.hasNext()) {
		Record rec = (Record) it.next();
		if (wild != null)
			rec = rec.withName(wild);
		records[--size] = rec.toWireCanonical();
	}
	Arrays.sort(records);
	for (int i = 0; i < records.length; i++)
		out.writeArray(records[i]);
	return out.toByteArray();
}

}

@@ -1101,295 +1101,80 @@
 1;%0A%0A
-/* %0A * Creates an array containing fields of the SIG record and the RRsets to%0A * be signed.  The output of this should be cryptographically signed or%0A * verified.%0A */%0Apublic static byte %5B%5D%0AdigestRRset(SIGRecord sig, RRset rrset) %7B%0A%09DataByteOutputStream out = new DataByteOutputStream();%0A
+private static void%0AdigestSIG(DataByteOutputStream out, SIGRecord sig) %7B
 %0A%09ou
@@ -1504,16 +1504,438 @@
 al(out);
+%0A%7D%0A%0A/**%0A * Creates an array containing fields of the SIG record and the RRsets to%0A * be signed/verified.%0A * @param sig The SIG record used to sign/verify the rrset.%0A * @param rrset The data to be signed/verified.%0A * @return The data to be cryptographically signed or verified.%0A */%0Apublic static byte %5B%5D%0AdigestRRset(SIGRecord sig, RRset rrset) %7B%0A%09DataByteOutputStream out = new DataByteOutputStream();%0A%09digestSIG(out, sig);
 %0A%0A%09int s
@@ -2381,16 +2381,16 @@
 h; i++)%0A
-
 %09%09out.wr
@@ -2441,10 +2441,616 @@
 y();%0A%7D%0A%0A
+/**%0A * Creates an array containing fields of the SIG record and the message to%0A * be signed.%0A * @param sig The SIG record used to sign/verify the rrset.%0A * @param msg The message to be signed/verified.%0A * @param previous If this is a response, the signature from the query.%0A * @return The data to be cryptographically signed or verified.%0A */%0Apublic static byte %5B%5D%0AdigestMessage(SIGRecord sig, Message msg, byte %5B%5D previous) %7B%0A%09DataByteOutputStream out = new DataByteOutputStream();%0A%09digestSIG(out, sig);%0A%0A%09if (previous != null)%0A%09%09out.writeArray(previous);%0A%09%0A%09msg.toWire(out);%0A%09return out.toByteArray();%0A%7D%0A%0A
 %7D%0A

Add digestMessage(), to be used for SIG(0).