All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xbill.DNS.security.DSASignature Maven / Gradle / Ivy

There is a newer version: 2.0-beta-7
Show newest version
// Copyright (c) 1999-2004 Brian Wellington ([email protected])

package org.xbill.DNS.security;

import java.security.SignatureException;
import java.security.interfaces.DSAParams;
import java.util.Arrays;

/**
 * Converts DSA signatures between the RRSIG/SIG record format (as specified
 * in RFC 2536) and the format used by Java DSA routines (DER-encoded).
 *
 * @author Brian Wellington
 */

public class DSASignature {

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

private DSASignature() {}

/**
 * Converts the signature field in a SIG record to the
 * format expected by the DSA verification routines.
 */
public static byte []
fromDNS(byte [] sig) {
	final int len = 20;
	int n = 0;
	byte rlen, slen, seqlen;

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

	slen = len;
	if (sig[len + 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] = sig[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] = sig[1 + len + i];
	return array;
}

/**
 * Converts the signature generated by DSA signature routines to
 * the one expected inside an RRSIG/SIG record.
 */
public static byte []
toDNS(DSAParams params, byte [] sig)
throws SignatureException
{
	int rLength, sLength;
	int rOffset, sOffset;
	if ((sig[0] != ASN1_SEQ) || (sig[2] != ASN1_INT))
		throw new SignatureException("Expected SEQ, INT");
	rLength = sig[3];
	rOffset = 4;
	if (sig[rOffset] == 0) {
		rLength--;
		rOffset++;
	}
	if (sig[rOffset+rLength] != ASN1_INT)
		throw new SignatureException("Expected INT");
	sLength = sig[rOffset + rLength + 1];
	sOffset = rOffset + rLength + 2;
	if (sig[sOffset] == 0) {
		sLength--;
		sOffset++;
	}

	if ((rLength > 20) || (sLength > 20))
		throw new SignatureException("DSA R/S too long");

	byte[] newSig = new byte[41];
	Arrays.fill(newSig, (byte) 0);
	newSig[0] = (byte) ((params.getP().bitLength() - 512)/64);
	System.arraycopy(sig, rOffset, newSig, 1 + (20 - rLength), rLength);
	System.arraycopy(sig, sOffset, newSig, 21 + (20 - sLength), sLength);
	return newSig;
}
    
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy