Code Monkey home page Code Monkey logo

dnssecjava's Introduction

Archival notice

dnssecjava was merged into dnsjava and is a built-in resolver from v3.5.0 on.


dnssecjava

A DNSSEC validating stub resolver for Java.

Build Status Coverage Status Maven Central Javadocs

Is this library safe to use?

Maybe. There's been no audit of the code so far, so there are absolutely no guarantees. The rest depends currently on your use case: the proof that a positive response is correct should be safe to use. Most of the NXDOMAIN/NODATA responses are safe too, but there are some corner cases that have no tests yet.

Unit tests are currently covering over 95% of the code, including 133 from Unbound. Also keep in mind that while most of the code paths are covered by unit tests, this does not mean it is performing according to the RFCs or that something that should be checked for is really done.

See the To-Do list for more details.

History

This project is based on the work of the Unbound Java prototype from 2005/2006. The Unbound prototype was stripped from all unnecessary parts, heavily modified, complemented with more than 300 unit test and found bugs were fixed.

Released versions

  • 2.0.0:
    • Requires Java 8
    • Disable DSA (3) and DSA-NSEC3-SHA1 (6) algorithms by default (RFC 8624)
    • Add support for ECC-GOST (12) and EdDSA (15, 16) algorithms, see #21
    • Add support for async resolving using dnsjava 3, #23
  • 1.2.0:
    • Fix CVE-2017-15105
    • Add config option org.jitsi.dnssec.harden_algo_downgrade
    • Fix handling of ENT in NSEC3 zones
    • Fix returning YXDOMAIN RCode
    • Requires dnsjava 2.1.9 for proper (EC)DSA signature validation
  • 1.1.3:
    • Replace jmockit with PowerMockito due to ever changing API (and there's a Debian package for PowerMockito)
    • Use fixed versions for the dependencies
    • Fix a Javadoc error in ValUtils
  • 1.1.2:
    • Issue #7: Provide alternatve to the resource bundle mechanism (thanks to Matt David)
    • Issue #8: Fix parameter in dnskey.anchor_verify_failed (thanks to Andreas Schildbach)
  • 1.1.1: Issue #5: Avoid using a regex to split long validation reasons, they don't work on Android
  • 1.1: Change logging to slf4j
  • 1.0: Initial release

Usage

The project is intended to be used as a Resolver for DNSJAVA. Validated, secure responses contain the DNS AD-flag, while responses that failed validation return the SERVFAIL-RCode. Insecure responses return the actual return code without the AD-flag set. The reason why the validation failed or is insecure is provided as a localized string in the additional section under the record ./65280/TXT (a TXT record for the owner name of the root zone in the private query class ValidatingResolver.VALIDATION_REASON_QCLASS).

Example

import java.io.*;

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

public class ResolveExample {
    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("4.2.2.1");
        System.out.println("Standard resolver:");
        sendAndPrint(sr, "www.dnssec-failed.org.");
        sendAndPrint(sr, "www.isc.org.");

        // 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.");
        sendAndPrint(vr, "www.isc.org.");
    }

    private static void sendAndPrint(Resolver vr, String name) throws IOException {
        System.out.println("\n---" + name);
        Record qr = Record.newRecord(Name.fromConstantString(name), Type.A, 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));
            }
        }
    }
}

This should result in an output like

Standard resolver:
---www.dnssec-failed.org.
AD-Flag: false
RCode:   NOERROR
---www.isc.org.
AD-Flag: false
RCode:   NOERROR

Validating resolver:
---www.dnssec-failed.org.
AD-Flag: false
RCode:   SERVFAIL
Reason:  Could not establish a chain of trust to keys for [dnssec-failed.org.]. Reason: Did not match a DS to a DNSKEY.
---www.isc.org.
AD-Flag: true
RCode:   NOERROR

Build

Run mvn package

Configuration Options

The validator supports a few configuration options. These can be set by calling ValidatingResolver.init(properties);

org.jitsi.dnssec.keycache.max_ttl

Maximum time-to-live (TTL) of entries in the key cache in seconds. The default is 900s (15min).

org.jitsi.dnssec.keycache.max_size

Maximum number of entries in the key cache. The default is 1000.

org.jitsi.dnssec.nsec3.iterations.N

Maximum iteration count for the NSEC3 hashing function depending on the key size N. The defaults from RFC5155 are:

  • 1024 bit keys: 150 iterations (i.e. org.jitsi.dnssec.nsec3.iterations.1024=150)
  • 2048 bit keys: 500 iterations
  • 4096 bit keys: 2500 iterations

org.jitsi.dnssec.trust_anchor_file

The file from which the trust anchor should be loaded. There is no default.

It must be formatted like a DNS zone master file. It can only contain DS or DNSKEY records.

org.jitsi.dnssec.digest_preference

Defines the preferred DS record digest algorithm if a zone has registered multiple DS records. The list is comma-separated, highest preference first.

If this property is not specified, the DS record with the highest [digest ID] (http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml) is chosen. To stay compliant with the RFCs, the mandatory digest IDs must be listed in this property.

The GOST digest requires BouncyCastle on the classpath.

org.jitsi.dnssec.harden_algo_downgrade

Prevent algorithm downgrade when multiple algorithms are advertised in a zones DS records. If false, allows any algorithm to validate the zone. Default is true.

org.jitsi.dnssec.digest_enabled.ID

Boolean property to enable or disable a DS record digest algorithm. See RFC8624 for recommended values.

org.jitsi.dnssec.algorithm_enabled.ID

Boolean property to enable or disable a DS/DNSKEY algorithm. See RFC8624 for recommended values.

dnssecjava's People

Contributors

dependabot[bot] avatar flowdalic avatar ibauersachs avatar schildbach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dnssecjava's Issues

Release dnssecjava 1.1 with slf4j changes

Hey Ingo,

Everything is looking great so far with our use of your awesome library! Can you please release a 1.1 version of the library to the repository so that the slf4j changes are in a released state? Thanks sir! :)

Support for dnsjava 3

dnssecjava is not compatible with the changed api of dnsjavva 3

it results in the following error.

java.lang.NoSuchMethodError: 'org.xbill.DNS.RRset[] org.xbill.DNS.Message.getSectionRRsets(int)'
at org.jitsi.dnssec.SMessage.(SMessage.java:114)
at org.jitsi.dnssec.validator.ValidatingResolver.sendRequest(ValidatingResolver.java:675)
at org.jitsi.dnssec.validator.ValidatingResolver.send(ValidatingResolver.java:1219)

nsec3 issue with sgkb.ch

sgkb.ch's mail is operated (like many others such as tkb.ch) by swisscom and all worked fine till Aug 2, 2019
Now we get

INFO [Thread-133881] (DnsSecVerifier.java:209) - RRset failed to verify: all signatures were BOGUS
DEBUG [Thread-133881] (ValUtils.java:309) - verifySRRset: rrset <51kk3ii7rptu8ph8oa9tpn65ndhdh51c.ch./NSEC3/IN> found to be BAD
DEBUG [Thread-133881] (ValidatingResolver.java:943) - skipping bad nsec3
DEBUG [Thread-133881] (NSEC3ValUtils.java:367) - Could not find proof that the closest encloser was the closest encloser
DEBUG [Thread-133881] (KeyEntry.java:198) - NSEC3s proved bogus.
DEBUG [Thread-133881] (ValidatingResolver.java:1044) - processKeyValidate: no signerName.
DEBUG [Thread-133881] (SMessage.java:239) - Could not establish validation of INSECURE status of unsigned response. Reason: NSEC3s proved bogus.>>

Alternatives like "dig" appear to be happy:
<< dig +dnssec mx sgkb.ch

; <<>> DiG 9.10.3-P4-Debian <<>> +dnssec mx sgkb.ch
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16667
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;sgkb.ch.                       IN      MX

;; ANSWER SECTION:
sgkb.ch.                3600    IN      MX      20 mail20.swisscom.com.
sgkb.ch.                3600    IN      MX      20 mail10.swisscom.com.
sgkb.ch.                3600    IN      MX      10 mail.swisscom.com.

;; Query time: 7 msec
;; SERVER: 212.25.1.1#53(212.25.1.1)
;; WHEN: Mon Aug 12 07:14:10 CEST 2019
;; MSG SIZE  rcvd: 115

Any hint who made an/the error would be useful ?

Very old log4j version

I noticed dnssecjava is using a very old log4j version. And it depends on a all-in-one JAR which depends on a lot classes/API not available under Android. This causes all sorts of build and runtime issues. I suggest switching the dependency to:

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.5</version>
</dependency>

I assume the API hasn't changed much, so this is probably a drop-in replacement.

OR: Even better, use the more modern SLF4J:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.18</version>
</dependency>

I can provide a PR for one of the options.

Root key rollover support

as took place today (https://www.iana.org/dnssec/files, https://www.heise.de/newsticker/meldung/DNS-Schluesselwechsel-Am-11-10-ist-es-so-weit-4179863.html)

ValidatingResolver.loadTrustAnchors(InputStream data)
so far took
". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"

and since today, it needs
". IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d"

Is it possible to just concatenate the 2 Strings with LF, or is there further potential for smooth roll-over support ?

Additional NS records in Authority section can cause validation failure

Dear all,

when trying to validate records of gmx.net a SERVFAIL response appears. Do you know what the issue might be and if there is a fix for would it be possible to update the project providing it?

Please find a small programm demonstrating this issue.

import java.io.ByteArrayInputStream;

import org.jitsi.dnssec.validator.ValidatingResolver;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Flags;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Rcode;
import org.xbill.DNS.Record;
import org.xbill.DNS.Section;
import org.xbill.DNS.SimpleResolver;
import org.xbill.DNS.TXTRecord;
import org.xbill.DNS.Type;

/**

  • Simple dnssecjava example demonstrating SERVFAIL response for Name "gmx.net." (using our internal DNS server),
  • while https://dnssec-analyzer.verisignlabs.com/gmx.net shows an "all-green" result using their default DNS server.
  • However, depending on the DNS server, VeriSign's online DNSSEC analyzer shows different results:
  • Okay: FreeDNS 45.33.97.5, UncensoredDNS 91.239.100.100, Hurricane Electric 74.82.42.42
  • Warnings: Yandex.DNS 77.88.8.8, puntCAT 109.69.8.51, Cloudflare 1.1.1.1
  • All other DNS servers listed at https://www.lifewire.com/free-and-public-dns-servers-2626062 produce errors.
    */
    public class DnssecjavaDemo
    {
    public static void main(String[] args) throws Exception
    {
    ValidatingResolver vr = new ValidatingResolver(new SimpleResolver());
    String ROOT = ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D";
    vr.loadTrustAnchors(new ByteArrayInputStream(ROOT.getBytes("ASCII")));
    Record qr = Record.newRecord(Name.fromConstantString("gmx.net."), Type.A, 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));
    }
    }
    }
    }

Thank you very much.

Best Regards

Vangelis

java.naming.factory.initial ==> DnsSecContextFactory ?

E.g. in badpenguin.dkim, the following approach to DNS lookup is used:

	Hashtable<String,String> env = new Hashtable<String,String>();	
	env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
	env.put("java.naming.provider.url", "dns://" + nameServer );
	dnsCtx = new InitialDirContext(env);
            ...
	Attributes attrs = null;
	try {
		attrs = dnsCtx.getAttributes(lookup, new String[] {"txt"});
	} catch (NamingException e) {
                  ...

Could your code be fit into something like

public class DnsSecContextFactory extends DnsContextFactory {
    ...

?

Release version 1.0

I see this project is already in use by other projects/libraries. It would be nice to release a first version so stable dependencies can be maintained.

PatternSyntaxException: Look-behind pattern matches must have a bounded maximum length

I'm seeing this on version 1.1:

java.util.regex.PatternSyntaxException: Look-behind pattern matches must have a bounded maximum length near index 13:
(?<=\G.{255})
             ^
    at java.util.regex.Pattern.compileImpl(Native Method) ~[na:0.0]
    at java.util.regex.Pattern.compile(Pattern.java:407) ~[na:0.0]
    at java.util.regex.Pattern.<init>(Pattern.java:390) ~[na:0.0]
    at java.util.regex.Pattern.compile(Pattern.java:381) ~[na:0.0]
    at java.lang.String.split(String.java:1832) ~[na:0.0]
    at java.lang.String.split(String.java:1813) ~[na:0.0]
    at org.jitsi.dnssec.validator.ValidatingResolver.send(ValidatingResolver.java:1240) ~[na:0.0]
    at com.netki.dnssec.DNSSECResolver.resolve(DNSSECResolver.java:122) ~[na:0.0]
    at com.netki.WalletNameResolver.resolve(WalletNameResolver.java:149) ~[na:0.0]

Java 6/Java 7 compatible jar

Thank you for this library, it is very useful in my case. One remark: the 1.2.0 jar from Maven central appears to be only suitable for Java 8 or higher version, despite the pom.xml from this project indicating Java 6 or higher.
I recompiled the 1.2.0 version using a modified pom (packaging set to "jar") and Java 8 - this does result in a jar-file that is at least compatible with Java 7 (I have not tested with Java 6).

Provide alternative to the resource bundle mechanism

Dnssecjava pulls strings from a messages.properties. Unfortunately, Android does not have this mechanism. This results in an exception whenever R.get() is called, e.g.:

Caused by: java.util.MissingResourceException: Can't find resource for bundle 'messages_en_US', key ''
at java.util.ResourceBundle.missingResourceException(ResourceBundle.java:238)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:230)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:139)
at org.jitsi.dnssec.R.<clinit>(R.java:20)

Support of ECDSA key to DNSKEY ?

Does the current ValidatingResolver already support this new algorithm ?


From: Daniel Stirnimann [email protected]
Subject: [swinog] .CH/.LI DNSSEC Algorithm Rollover
Date: 12 November 2018 at 08:45:28 CET
To: [email protected]

Hello,

for your information, SWITCH will perform a DNSSEC algorithm rollover
from RSA to ECDSA for ch. and li.

ECDSA uses smaller keys and signatures than their RSA counterparts,
which means responses to DNS queries are smaller.

ECDSA was already standardised for use in DNSSEC in 2012. While
switch.ch has been signed with ECDSA since 2016, IANA the root zone
operator has only recently allowed TLDs to use it.

The changes to the ch. and li. zones DNSKEY record are as following with
times reported in UTC:

2018-11-21T13:30 Add new ECDSA key to DNSKEY record set
2018-12-21T13:30 Remove old RSA key from DNSKEY record set

Between this interval, the chain of trust for ch. and li. will be
updated in the root zone to point to the new ECDSA key only.

Operators of DNSSEC validating DNS resolvers do not need to do anything.
In the unlikely case that your validating DNS resolver only understands
RSA but not ECDSA, then it will answer to ch. or li. queries as if they
were not DNSSEC signed.

You can test which DNSSEC algorithms are supported by the DNS
resolver(s) configured on your system by visiting:
https://rootcanary.org/test.html

Best regards,
Daniel Stirnimann, SWITCH

--
SWITCH
Daniel Stirnimann, SWITCH-CERT
Werdstrasse 2, P.O. Box, 8021 Zurich, Switzerland
phone +41 44 268 15 15, direct +41 44 268 16 24
[email protected], www.switch.ch


swinog mailing list
[email protected]
http://lists.swinog.ch/cgi-bin/mailman/listinfo/swinog

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

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

TrustAnchorStore lookup method is case sensitive

Repo steps:

  1. Initialize the following basic trustAnchor for the root and gallup TLD:
.			0	IN	DS	19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
.			0	IN	DS	20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
GALLUP.			86400	IN	DS	34159 8 2 AE9BBA11562A260AAA062E2EB9881443044FDB8998B6A81C25D34D0D6BF49CB5
  1. Then call
validatingResolver
          .loadTrustAnchors(new ByteArrayInputStream(trustAnchor.toString().getBytes()))
  1. Then send any dns query, say GALLUP., type = DNSKEY, class = IN

The response will contain the following bogus reason:

Could not establish a chain of trust to keys for [.]. Reason: Missing DNSKEY RRset in response to DNSKEY query for ..

Nevertheless gallup is in the chain of trust: https://dnssec-analyzer.verisignlabs.com/nic.gallup

This seems to be a bug in the TrustAnchorStore lookup method that compare the gallup key with GALLUP and fail to find it.

Thank you for this awesome lib by the way and best regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.