Skip to content
This repository has been archived by the owner on Feb 6, 2022. It is now read-only.

Leading zeroes in in (r|s)-parameters of ECDSA signature cause validation to fail #14

Closed
ralfhauser opened this issue Jan 22, 2019 · 14 comments

Comments

@ralfhauser
Copy link

since this morning, we get
. 0 CLASS65280 TXT "Could not establish validation of INSECURE status of unsigned response. Reason: Did not match a DS to a DNSKEY."

e.g. for MX of bger.ch

any hints what wrong ?

212.25.1.1 is the resolver.

<<query: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15318
;; flags: rd ; qd: 1 an: 0 au: 0 ad: 0
;; QUESTIONS:
;; bger.ch., type = MX, class = IN

;; ANSWERS:

;; AUTHORITY RECORDS:

;; ADDITIONAL RECORDS:

;; Message size: 0 bytes
DEBUG [Thread-106] - got response: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 15318
;; flags: qr ; qd: 1 an: 0 au: 0 ad: 1
;; QUESTIONS:
;; bger.ch., type = MX, class = IN

;; ANSWERS:

;; AUTHORITY RECORDS:

;; ADDITIONAL RECORDS:
. 0 CLASS65280 TXT "Could not establish validation of INSECURE status of unsigned response. Reason: Did not match a DS to a DNSKEY."

iWay claims they didn't change anything and all is working properly

@ibauersachs
Copy link
Owner

I can't access your resolver, so I have no idea what's going on there. A simple test based on the example in the readme and Google's public DNS or our internal AD resolver shows no errors:

package org.jitsi.dnssec;
import java.io.*;

import org.jitsi.dnssec.validator.ValidatingResolver;
import org.xbill.DNS.*;

public class Example {
    static String ROOT = ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D";

    public static void main(String[] args) throws Exception {
        // Send two sample queries using a standard DNSJAVA resolver
        SimpleResolver sr = new SimpleResolver("8.8.4.4");
        System.out.println("Standard resolver:");
        sendAndPrint(sr, "www.dnssec-failed.org.", Type.A);
        sendAndPrint(sr, "www.isc.org.", Type.A);
        sendAndPrint(sr, "bger.ch.", Type.MX);

        // Send the same queries using the validating resolver with the
        // trust anchor of the root zone
        // http://data.iana.org/root-anchors/root-anchors.xml
        ValidatingResolver vr = new ValidatingResolver(sr);
        vr.loadTrustAnchors(new ByteArrayInputStream(ROOT.getBytes("ASCII")));
        System.out.println("\n\nValidating resolver:");
        sendAndPrint(vr, "www.dnssec-failed.org.", Type.A);
        sendAndPrint(vr, "www.isc.org.", Type.A);
        sendAndPrint(sr, "bger.ch.", Type.MX);
    }

    private static void sendAndPrint(Resolver vr, String name, int type) throws IOException {
        System.out.println("\n---" + name);
        Record qr = Record.newRecord(Name.fromConstantString(name), type, DClass.IN);
        Message response = vr.send(Message.newQuery(qr));
        System.out.println("AD-Flag: " + response.getHeader().getFlag(Flags.AD));
        System.out.println("RCode:   " + Rcode.string(response.getRcode()));
        for (RRset set : response.getSectionRRsets(Section.ADDITIONAL)) {
            if (set.getName().equals(Name.root) && set.getType() == Type.TXT
                    && set.getDClass() == ValidatingResolver.VALIDATION_REASON_QCLASS) {
                System.out.println("Reason:  " + ((TXTRecord) set.first()).getStrings().get(0));
            }
        }
    }
}

Result:

Standard resolver:

---www.dnssec-failed.org.
AD-Flag: false
RCode:   SERVFAIL

---www.isc.org.
AD-Flag: false
RCode:   NOERROR

---bger.ch.
AD-Flag: false
RCode:   NOERROR


Validating resolver:

---www.dnssec-failed.org.
AD-Flag: false
RCode:   SERVFAIL
Reason:  validate.bogus.badkey:dnssec-failed.org.:dnskey.no_ds_match

---www.isc.org.
AD-Flag: true
RCode:   NOERROR

---bger.ch.
AD-Flag: false
RCode:   NOERROR

@ralfhauser
Copy link
Author

now also seeing

CLASS65280 TXT "Could not establish a chain of trust to keys for [ch.]. Reason: Did not match a DS to a DNSKEY."

@ralfhauser
Copy link
Author

The problem can also be reproduced with 8.8.4.4

Your test probably has a copy-paste error.

Also the 2nd time you do:
sendAndPrint(sr, "bger.ch.", Type.MX);
but probably you should do
sendAndPrint(vr, "bger.ch.", Type.MX);

==> did you really test bger with "vr" ?

@ibauersachs
Copy link
Owner

No, sorry, copy/paste. Seems like Switch generated a signature that has a leading 0, which Java since 1.8.121 rejects. See https://stackoverflow.com/a/40343731/1544715 for details (they talk about RSA but it applies to ECDSA as well). Not sure yet where to satisfy Java's (or BouncyCastle's) stupidity.

java.io.IOException: Invalid encoding: redundant leading 0s
	at java.base/sun.security.util.DerInputBuffer.getBigInteger(DerInputBuffer.java:161)
	at java.base/sun.security.util.DerValue.getPositiveBigInteger(DerValue.java:558)
	at jdk.crypto.ec/sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:491)
	at jdk.crypto.ec/sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:412)
	at java.base/java.security.Signature$Delegate.engineVerify(Signature.java:1247)
	at java.base/java.security.Signature.verify(Signature.java:675)
	at org.xbill.DNS.DNSSEC.verify(DNSSEC.java:892)
	at org.xbill.DNS.DNSSEC.verify(DNSSEC.java:934)
	at org.jitsi.dnssec.validator.DnsSecVerifier.verify(DnsSecVerifier.java:198)
	at org.jitsi.dnssec.validator.ValUtils.verifyNewDNSKEYs(ValUtils.java:232)
	at org.jitsi.dnssec.validator.ValidatingResolver.processDNSKEYResponse(ValidatingResolver.java:982)
	at org.jitsi.dnssec.validator.ValidatingResolver.processFindKey(ValidatingResolver.java:779)
	at org.jitsi.dnssec.validator.ValidatingResolver.processDSResponse(ValidatingResolver.java:967)
	at org.jitsi.dnssec.validator.ValidatingResolver.processFindKey(ValidatingResolver.java:772)
	at org.jitsi.dnssec.validator.ValidatingResolver.processDNSKEYResponse(ValidatingResolver.java:994)
	at org.jitsi.dnssec.validator.ValidatingResolver.processFindKey(ValidatingResolver.java:779)
	at org.jitsi.dnssec.validator.ValidatingResolver.prepareFindKey(ValidatingResolver.java:715)
	at org.jitsi.dnssec.validator.ValidatingResolver.validateAnswerAndGetWildcards(ValidatingResolver.java:390)
	at org.jitsi.dnssec.validator.ValidatingResolver.validatePositiveResponse(ValidatingResolver.java:257)
	at org.jitsi.dnssec.validator.ValidatingResolver.processValidate(ValidatingResolver.java:1047)
	at org.jitsi.dnssec.validator.ValidatingResolver.send(ValidatingResolver.java:1236)
	at org.jitsi.dnssec.Example.sendAndPrint(Example.java:37)
	at org.jitsi.dnssec.Example.main(Example.java:31)

@ibauersachs ibauersachs reopened this Jan 22, 2019
@ibauersachs ibauersachs changed the title error "Did not match a DS to a DNSKEY" for MX lookup of non-dnssec domain bger.ch Leading zeroes in in (r|s)-parameters of ECDSA signature cause validation to fail Jan 22, 2019
@Habbie
Copy link

Habbie commented Jan 23, 2019

dblacka/jdnssec-tools#4 might be of interest.

@gryphius
Copy link

I tried out @Habbie s patch in dnsjava by simply replacing ECDSASignaturefromDNS with his fixed convertECDSASignature . This makes my test program happily validate the .ch DNSKEY RRSET with current java(1.8.0_201) again.

gryphius/dnsjava@b4216b3

My test case:

package sigbugtest;

import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
import org.xbill.DNS.DClass;



public class SigBug {

	public static void main(String[] args) throws Exception {
		RRset rrset = new RRset();
		Record ksk = Record.fromString(Name.fromString("ch."), Type.DNSKEY, DClass.IN, 3600l,
				"257 3 13 Cm86XmSSO2FbG/3i9I++7HrRGNa1hNBZ1P7Y38Rg8uUz4YsKWSahAifo yaNMFWUu32VFj5xJQOEjqkrwD3Decw==",
				Name.fromString("ch."));
		rrset.addRR(Record.fromString(Name.fromString("ch."), Type.DNSKEY, DClass.IN, 3600l,
				"256 3 13 Qv739sZhsOAXaYY+2k0ZRr24bvi3Aae0w4JcYds9NQVp+qZbDFIWDMbB rjmELzgpAIXvdfoZScm7VD8iMrlnJQ==",
				Name.fromString("ch.")));
		rrset.addRR(ksk);
		rrset.addRR(Record.fromString(Name.fromString("ch."), Type.DNSKEY, DClass.IN, 3600l,
				"256 3 13 c/8Ej2lq1l1r/tCXl90QWJKIPGLRzwp3dTWAAw8BwsC5Ya9rBzZupYWU fY3aLGl5k8qbRcNXxacINKkWv8ahfA==",
				Name.fromString("ch.")));

		RRSIGRecord rrsig = (RRSIGRecord) Record.fromString(Name.fromString("ch."), Type.RRSIG, DClass.IN, 3600l,
				"DNSKEY 13 1 86400 20190307100909 20190120090909 11896 ch. RNSzPMRKwopYI3vwbwdpWulDrBYMn6Aappw4KXKEpUgAF9vb8DDF0GHY B5v4Af7zMTRgBoGFoPTxmjmBPJAMzA==",
				Name.fromString("ch."));

		DNSSEC.verify(rrset, rrsig, (DNSKEYRecord) ksk);
		System.out.println("SIG VERIFICATION OK");
	}

}

older java ( 1.8.0_111 ) + unpatched dnsjava validates ok
current java + unpatched dnsjava fails
current java + patched dnsjava validates ok

@ibauersachs
Copy link
Owner

@gryphius / @Habbie could you please forward that patch to the dnsjava mailing list (dnsjava-users@lists.sourceforge.net) and ask Brian to do a release?

@ralfhauser
Copy link
Author

reported to https://sourceforge.net/p/dnsjava/bugs/64/

@primetomas
Copy link

I can confirm that we tested this patch and it works for us.

@ralfhauser
Copy link
Author

Due to multiple non-response to https://sourceforge.net/p/dnsjava/bugs/64/

https://github.com/xbill-dns/dns has been created to fix the above.

If you fix the problem on sf.net or are willing to continue maintaining this good software on github, it's all your's!

@mwullink
Copy link

mwullink commented Apr 1, 2019

this fix is great, it fixed my problems with the ECDSA signature.
too bad this fix is not included in the original dnsjava project.

@ibauersachs
Copy link
Owner

@mwullink so far, nobody has submitted a patch to the dnsjava mailing list.

@ralfhauser
Copy link
Author

@ibauersachs but a pull request dnsjava/dnsjava#17 - isn't that even more effective than a patch ?

@mwullink
Copy link

mwullink commented Apr 2, 2019

The maintainer of dnsjava says he has no plans to work on the project in the near future.

https://sourceforge.net/p/dnsjava/discussion/57043/thread/132c7639a4/?limit=25#eaf6

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants