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

package org.xbill.DNS.security;

import org.xbill.DNS.*;

/**
 * Converts the DSA signature in a SIG Record to the format expected by
 * the DSA verification routines.
 *
 * @author Brian Wellington
 */

class DSASignature {

static final int ASN1_SEQ = 0x30;
static final int ASN1_INT = 0x2;

static byte []
create(SIGRecord sigrec) {
	final int len = 20;
	int n = 0;
	byte rlen, slen, seqlen;

	byte [] sigdata = sigrec.getSignature();

	rlen = len;
	if (sigdata[1] < 0)
		rlen++;

	slen = len;
	if (sigdata[1] < 0)
		slen++;

	/* 4 = 2 * (INT, value) */
	seqlen = (byte) (rlen + slen + 4);

	/* 2 = 1 * (SEQ, value) */
	byte [] array = new byte[seqlen + 2];

	array[n++] = ASN1_SEQ;
	array[n++] = (byte) seqlen;
	array[n++] = ASN1_INT;
	array[n++] = rlen;
	if (rlen > len)
		array[n++] = 0;
	for (int i = 0; i < len; i++, n++)
		array[n] = sigdata[1 + i];
	array[n++] = ASN1_INT;
	array[n++] = slen;
	if (slen > len)
		array[n++] = 0;
	for (int i = 0; i < len; i++, n++)
		array[n] = sigdata[1 + len + i];
	return array;
}

}

@@ -143,16 +143,125 @@
 urity;%0A%0A
+import java.security.SignatureException;%0Aimport java.security.interfaces.DSAParams;%0Aimport java.util.Arrays;%0A
 import o
@@ -293,20 +293,16 @@
 onverts 
-the 
 DSA sign
@@ -310,83 +310,124 @@
 ture
- in a
+s between the
  SIG 
-R
+r
 ecord 
-to the format expected by%0A * the DSA verification routines
+format (as specified%0A * in RFC 2536) and the format used by Java DSA routines (DER-encoded)
 .%0A *
@@ -460,16 +460,23 @@
 on%0A */%0A%0A
+public 
 class DS
@@ -557,16 +557,132 @@
 = 0x2;%0A%0A
+/**%0A * Converts the signature field in a SIG record to the%0A * format expected by the DSA verification routines.%0A */%0A
 static b
@@ -1406,10 +1406,1039 @@
 ray;%0A%7D%0A%0A
-%7D
+/**%0A * Converts the signature generated by DSA signature routines to%0A * the one expected inside a SIG record.%0A */%0Astatic byte %5B%5D%0Acreate(DSAParams params, byte %5B%5D sig)%0Athrows SignatureException%0A%7B%0A%09int rLength, sLength;%0A%09int rOffset, sOffset;%0A%09if ((sig%5B0%5D != ASN1_SEQ) %7C%7C (sig%5B2%5D != ASN1_INT))%0A%09%09throw new SignatureException(%22Expected SEQ, INT%22);%0A%09rLength = sig%5B3%5D;%0A%09rOffset = 4;%0A%09if (sig%5BrOffset%5D == 0) %7B%0A%09%09rLength--;%0A%09%09rOffset++;%0A%09%7D%0A%09if (sig%5BrOffset+rLength%5D != ASN1_INT)%0A%09%09throw new SignatureException(%22Expected INT%22);%0A%09sLength = sig%5BrOffset + rLength + 1%5D;%0A%09sOffset = rOffset + rLength + 2;%0A%09if (sig%5BsOffset%5D == 0) %7B%0A%09%09sLength--;%0A%09%09sOffset++;%0A%09%7D%0A%0A%09if ((rLength %3E 20) %7C%7C (sLength %3E 20))%0A%09%09throw new SignatureException(%22DSA R/S too long%22);%0A%0A%09byte%5B%5D newSig = new byte%5B41%5D;%0A%09Arrays.fill(newSig, (byte) 0);%0A%09newSig%5B0%5D = (byte) ((params.getP().bitLength() - 512)/64);%0A%09System.arraycopy(sig, rOffset, newSig, 1 + (20 - rLength), rLength);%0A%09System.arraycopy(sig, sOffset, newSig, 21 + (20 - sLength), sLength);%0A%09return newSig;%0A%7D%0A    %0A%7D%0A
 %0A

convert a dsa signature into a SIG record.