Skip to content

Commit

Permalink
use jdnssec-tools patch for leading zeroes padding
Browse files Browse the repository at this point in the history
  • Loading branch information
gryphius committed Jan 23, 2019
1 parent d97b6a0 commit b4216b3
Showing 1 changed file with 62 additions and 40 deletions.
102 changes: 62 additions & 40 deletions org/xbill/DNS/DNSSEC.java
Original file line number Diff line number Diff line change
Expand Up @@ -775,42 +775,67 @@ private static class ECKeyInfo {
return signature;
}

private static byte []
ECDSASignaturefromDNS(byte [] signature, ECKeyInfo keyinfo)
throws DNSSECException, IOException
{
if (signature.length != keyinfo.length * 2)
throw new SignatureVerificationException();

DNSInput in = new DNSInput(signature);
DNSOutput out = new DNSOutput();

byte [] r = in.readByteArray(keyinfo.length);
int rlen = keyinfo.length;
if (r[0] < 0)
rlen++;

byte [] s = in.readByteArray(keyinfo.length);
int slen = keyinfo.length;
if (s[0] < 0)
slen++;

out.writeU8(ASN1_SEQ);
out.writeU8(rlen + slen + 4);

out.writeU8(ASN1_INT);
out.writeU8(rlen);
if (rlen > keyinfo.length)
out.writeU8(0);
out.writeByteArray(r);

out.writeU8(ASN1_INT);
out.writeU8(slen);
if (slen > keyinfo.length)
out.writeU8(0);
out.writeByteArray(s);

return out.toByteArray();
/**
* Convert a DNS standard ECDSA signature (defined in RFC 6605) into a
* JCE standard ECDSA signature, which is encoded in ASN.1.
*
* The format of the ASN.1 signature is
*
* ASN1_SEQ . seq_length . ASN1_INT . r_length . R . ANS1_INT . s_length . S
*
* where R and S may have a leading zero byte if without it the values would
* be negative.
*
* The format of the DNSSEC signature is just R . S where R and S are both
* exactly "length" bytes.
*
* @param signature
* The binary signature data from an RRSIG record.
* @return signature data that may be used in a JCE Signature object for
* verification purposes.
*/
public static byte[] convertECDSASignature(byte[] signature)
{
byte r_src_pos, r_src_len, r_pad, s_src_pos, s_src_len, s_pad, len;

r_src_len = s_src_len = (byte) (signature.length / 2);
r_src_pos = 0; r_pad = 0;
s_src_pos = (byte) (r_src_pos + r_src_len); s_pad = 0;
len = (byte) (6 + r_src_len + s_src_len);

// leading zeroes are forbidden
if (signature[r_src_pos] == 0) {
r_src_pos++; r_src_len--; len--;
}
if (signature[s_src_pos] == 0) {
s_src_pos++; s_src_len--; len--;
}

// except when they are mandatory
if (signature[r_src_pos] < 0) {
r_pad = 1; len++;
}
if (signature[s_src_pos] < 0) {
s_pad = 1; len++;
}
byte[] sig = new byte[len];
byte pos = 0;

sig[pos++] = ASN1_SEQ;
sig[pos++] = (byte) (len - 2);
sig[pos++] = ASN1_INT;
sig[pos++] = (byte) (r_src_len + r_pad);
pos += r_pad;
System.arraycopy(signature, r_src_pos, sig, pos, r_src_len);
pos += r_src_len;

sig[pos++] = ASN1_INT;
sig[pos++] = (byte) (s_src_len + s_pad);
pos += s_pad;
System.arraycopy(signature, s_src_pos, sig, pos, s_src_len);

return sig;
}

private static byte []
Expand Down Expand Up @@ -869,13 +894,10 @@ private static class ECKeyInfo {
GOST);
break;
case Algorithm.ECDSAP256SHA256:
signature = ECDSASignaturefromDNS(signature,
ECDSA_P256);
break;
case Algorithm.ECDSAP384SHA384:
signature = ECDSASignaturefromDNS(signature,
ECDSA_P384);
signature = convertECDSASignature(signature);
break;

default:
throw new UnsupportedAlgorithmException(alg);
}
Expand Down

0 comments on commit b4216b3

Please sign in to comment.