Commit Graph
23 Commits
Author SHA1 Message Date
Ximon EighteenandGitHub 3ae459a4d6 In-place zone parser yields incorrect TTLs. (fixes #537) (#538) 2025-06-04 10:27:46 +02:00
Ximon EighteenandGitHub 3d3fe59177 Require single class zonefiles by default, and give context if possible on parsing errors. (#477)
- Extend the inplace zone parser to detect violations of the RFC 1035 section 5.2 requirement that a zonefile consist of exactly one class, enabled by default, and extend its error reporting to say what the wrong and expected classes were (and also use this contextual error support for other errors where applicable).

- Remove the default IN last class and allow the last class to be set if needed, as RFC 1035 doesn't define a default class.
2025-04-01 16:07:57 +02:00
0e854cf4da DNSSEC signing improvements and general crypto and DNSSEC restructuring (#416)
---------

Co-authored-by: arya dradjica <arya@nlnetlabs.nl>
Co-authored-by: Jannik Peters <jannik.peters@posteo.de>
Co-authored-by: Martin Hoffmann <martin@nlnetlabs.nl>
Co-authored-by: Ximon Eighteen <ximon@nlnetlabs.nl>
2025-04-01 10:04:09 +02:00
Ximon EighteenandGitHub 4667b9157e FIX: Don't error with unexpected end of entry for RFC 3597 RDATA of length zero. (#475) 2025-03-31 21:45:49 +02:00
8e8d616ee2 Loading, storing, and generating DNSSEC keys (#406)
* [sign] Define 'KeyPair' and impl key export

A private key converted into a 'KeyPair' can be exported in the
conventional DNS format.  This is an important step in implementing
'ldns-keygen' using 'domain'.  It is up to the implementation modules
to provide conversion to and from 'KeyPair'; some impls (e.g. for HSMs)
won't support it at all.

* [sign] Define trait 'Sign'

'Sign' is a more generic version of 'sign::key::SigningKey' that does
not provide public key information.  It does not try to abstract over
all the functionality of a keypair, since that can depend on the
underlying cryptographic implementation.

* [sign] Implement parsing from the DNS format

There are probably lots of bugs in this implementation, I'll add some
tests soon.

* [sign] Provide some error information

Also fixes 'cargo clippy' issues, particularly with the MSRV.

* [sign] Move 'KeyPair' to 'generic::SecretKey'

I'm going to add a corresponding 'PublicKey' type, at which point it
becomes important to differentiate from the generic representations and
actual cryptographic implementations.

* [sign/generic] Add 'PublicKey'

* [sign] Rewrite the 'ring' module to use the 'Sign' trait

Key generation, for now, will only be provided by the OpenSSL backend
(coming soon).  However, generic keys (for RSA/SHA-256 or Ed25519) can
be imported into the Ring backend and used freely.

* Implement DNSSEC signing with OpenSSL

The OpenSSL backend supports import from and export to generic secret
keys, making the formatting and parsing machinery for them usable.  The
next step is to implement generation of keys.

* [sign/openssl] Implement key generation

* [sign/openssl] Test key generation and import/export

* [sign/openssl] Add support for ECDSA

* [sign/openssl] satisfy clippy

* [sign/openssl] Implement the 'Sign' trait

* Install OpenSSL in CI builds

* Ensure 'openssl' dep supports 3.x.x

* [workflows/ci] Use 'vcpkg' instead of vendoring OpenSSL

* Ensure 'openssl' dep exposes necessary interfaces

* [workflows/ci] Record location of 'vcpkg'

* [workflows/ci] Use a YAML def for 'VCPKG_ROOT'

* [workflows/ci] Fix a vcpkg triplet to use

* Upgrade openssl to 0.10.57 for bitflags 2.x

* [workflows/ci] Use dynamic linking for vcpkg openssl

* [workflows/ci] Correctly annotate 'vcpkg'

* [sign/openssl] Implement exporting public keys

* [sign/ring] Implement exporting public keys

* [sign/generic] Test (de)serialization for generic secret keys

There were bugs in the Base64 encoding/decoding that are not worth
trying to debug; there's a perfectly usable Base64 implementation in
the crate already.

* [sign] Thoroughly test import/export in both backends

I had to swap out the RSA key since 'ring' found it to be too small.

* [sign] Remove debugging code and satisfy clippy

* [sign] Account for CR LF in tests

* [sign/openssl] Fix bugs in the signing procedure

- RSA signatures were being made with an unspecified padding scheme.
- ECDSA signatures were being output in ASN.1 DER format, instead of
  the fixed-size format required by DNSSEC (and output by 'ring').
- Tests for signature failures are now added for both backends.

* Refactor the 'sign' module

Most functions have been renamed.  The public key types have been moved
to the 'validate' module (which 'sign' now depends on), and they have
been outfitted with conversions (e.g. to and from DNSKEY records).

Importing a generic key into an OpenSSL or Ring key now requires the
public key to also be available.  In both implementations, the pair are
checked for consistency -- this ensures that both are uncorrupted and
that keys have not been mixed up.  This also allows the Ring backend to
support ECDSA keys (although key generation is still difficult).

The 'PublicKey' and 'PrivateKey' enums now store their array data in
'Box'.  This has two benefits: it is easier to securely manage memory
on the heap (since the compiler will not copy it around the stack); and
the smaller sizes of the types is beneficial (although negligibly) to
performance.

* Move 'sign' and 'validate' to unstable feature gates

* [workflows/ci] Document the vcpkg env vars

* Rename public/secret key interfaces to '*Raw*'

This makes space for higher-level interfaces which track DNSKEY flags
information (and possibly key rollover information).

* [sign/ring] Store the RNG in an 'Arc'

* [validate] Enhance 'Signature' API

* [validate] Add high-level 'Key' type

* [sign/openssl] Pad ECDSA keys when exporting

Tests would spuriously fail when generated keys were only 31 bytes in
size.

* [validate] Implement 'Key::key_tag()'

This is more efficient than allocating a DNSKEY record and computing
the key tag there.

* [validate] Correct bit offsets for flags

* [validate] Implement support for digests

The test keys have been rotated and replaced with KSKs since they have
associated DS records I can verify digests against.  I also expanded
Ring's testing to include ECDSA keys.  The validate module tests SHA-1
keys as well, which aren't supported by 'sign'.

* [validate] Enhance BIND format conversion for 'Key'

Public keys in the BIND format can now have multiple lines (even with
comments).  Keys can also be directly written into the BIND format and
round-trips to and from the BIND format are now tested.

* [sign] Introduce 'SigningKey'

* [sign] Handle errors more responsibly

The 'openssl' and 'ring' modules should now follow the contributing
guidelines regarding module layout and formatting.

* [sign] correct doc link

* [sign/openssl] Replace panics with results

* remove 'sign/key'

* [sign] Introduce 'common' for abstracting backends

This is useful for abstracting over OpenSSL and Ring, so that Ring can
be used whenever possible while OpenSSL is used as a fallback.  This is
useful for clients that just wish to support everything.

* [sign/generic] add top-level doc comment

* [validate] debug bind format errors

* [validate] more debug statements

* [validate] format DNSKEYs using 'ZonefileFmt'

The 'Dnskey' impl of 'fmt::Display' was no longer accurate to the zone
file format because 'SecAlg' now prints '<code>(<mnemonic>)'.

* Reorganize crate features in 'Cargo.toml'

* [sign] Add key generation support for Ring

It's a bit hacky because it relies on specific byte indices within the
generated PKCS8 documents (internally, Ring basically just concatenates
bytes to form the documents, and we use the same indices).  However,
any change to the document format should be caught by the tests here.

* [sign] Make OpenSSL support optional

Now that Ring and OpenSSL support all mandatory algorithms, OpenSSL is
no longer required in order to provide signing functionality.

* [sign] Rename 'generic::SecretKey' to 'KeyBytes'

* [sign] Rename 'SecretKey' to 'KeyPair' in all impls

* [sign] Rename 'KeyBytes' to 'SecretKeyBytes'

For consistency with the upcoming 'PublicKeyBytes'.

* [validate] Rename 'RawPublicKey' to 'PublicKeyBytes'

* [sign/ring] Remove redundant imports

* [sign,validate] Add 'display_as_bind()' to key bytes types

* [sign,validate] remove unused imports

* [sign] Document everything

* [lib] Rewrite feature flag documentation

* [workflows/ci] Use 'apt-get' instead of 'apt'

* [sign] Clarify documentation as per @ximon18

* [sign] Use 'secrecy' to protect private keys

* [sign] Improve documentation and examples

---------

Co-authored-by: arya dradjica <arya@nlnetlabs.nl>
2024-11-05 13:57:55 +01:00
Ximon EighteenandGitHub 7943f3da83 Fix indentation and remove unused settings in auth-zones test. (#402) 2024-10-07 14:27:24 +02:00
Ximon EighteenandGitHub a7e37e795c Various EDNS middleware fixes and improved Stelline test: (#355)
- Reply with FORMERR if an OPT RR cannot be parsed.
- Don't reply with FORMERR if an edns-tcp-keepalive option is received via UDP, instead ignore it per RFC 7828 3.2.1.
- Only reserve space for an edns-tcp-keepalive option for TCP requests, not UDP requests.
- Always reserve space for an OPT RR in the response for any request that has an OPT RR, not just TCP requests.
- Disable TCP client retries in Stelline server tests otherwise a connection abort causes a retry which violates the test expectation.
2024-10-03 16:22:41 +02:00
Ximon EighteenandGitHub f111cc6316 Set the AA flag and include glue in responses. (#400)
This PR adds handling of the AA flag and additional records to zonetree
answer generation.
2024-10-03 15:28:51 +02:00
Ximon EighteenandGitHub 01fccdf942 Add XFR middleware. (#384)
Add XFR middleware and:
- Fixes a bug where the incorrect owner name was passed to the zone walker callback.
- New `ixfr-client.rs` example.
- Updated `serve-zone.rs` example demonstrating TSIG authenticated XFR and NOTIFY middlewares.
- Additional From impls for CallResult.
- Renames ZoneDiff to InMemoryZoneDiff.
- Renames ZoneDiffBuilder to InMemoryZoneDiffBuilder.
- Introduces new ZoneDiff and related traits.
- Adds AnswerContent::first().
2024-10-02 21:28:01 +02:00
Ximon EighteenandGitHub 915388ce24 Add RFC 1996 NOTIFY support. (#382)
Add RFC 1996 "slave" side minimalistic NOTIFY request support, delegating the actual work to a caller supplied helper that implements a new Notifiable trait.
2024-09-24 20:43:53 +02:00
400843e226 Add TSIG middleware. (#380)
- Add TSIG response signing middleware.
- Update Stelline server integration tests to use the new TSIG middleware.
- Add TSIG Stelline test recipe.
- TSIG module changes:
  - Derive Clone for Key.
  - Added Key::compose_len() for determining how many response bytes to reserve.
  - Added ClientTransaction::wrapped_key(), ClientSequence::wrapped_key() and SigningContext::wrapped_key() to access the real underlying "wrapped" key type.
  - Added From<ServerTransaction<K>> for ServerSequence<K>.
  - Various minor RustDoc improvements.
 - Make Time48 obey mock (predictable and controllable) time so that TSIG signing uses mock time during Stelline tests.

Other:
- Remove unnecessary Unpin bounds on net::server::message::Request.
- Remove unnecessary Clone bound on impl SendRequest for net::client::dgram::Connection.
- Remove unnecessary mutex lock on middleware post-processing response state and rename PostprocessingConfig to PostprocessingState to better reflect its mutable nature.
- Don't set the AA flag on test service responses as (a) actual zone serving doesn't do this yet and this still needs fixing, and (b) it violates the expectations of the TSIG Stelline test that verifies at a byte level the TSIG response signature.

---------

Co-authored-by: Philip Homburg <philip@nlnetlabs.nl>
Co-authored-by: Philip-NLnetLabs <93709748+Philip-NLnetLabs@users.noreply.github.com>
Co-authored-by: Terts Diepraam <terts.diepraam@gmail.com>
2024-09-16 16:25:29 +02:00
Ximon EighteenandGitHub f3248b371d Stelline server testing changes for XFR and TSIG support. (#372)
- Added a simple UDP client that doesn't interfere with requests before sending (for TSIG testing).
- Added support for receiving multiple responses (for XFR testing).
- Added support for connection timeout errors
- Added support for connection termination errors (for EDNS testing).
- Added support for specifying the TSIG key to use (for TSIG testing).
- Added support for $ORIGIN in zone file fragments.
- Simplified rcode checking and use it instead of the yxrrset BADCOOKIE hack.
- In memory channel changes:
  - Fixed a trace message that incorrectly referred to client instead of server.
  - Fixed a too-tight connection read loop that was preventing Tokio task switching.
  - Added connection shutdown detection.
- Fixed incorrect setting of TCP mode to true when UDP mode was requested.
2024-09-09 20:22:55 +02:00
Ximon EighteenandGitHub ec5cb5bbb8 Re-enable and fix the Stelline cookies test (#336)
- Re-enable the cookies Stelline test and fix `CookiesMiddlewareProcessor` to allow requests with invalid cookies to proceed if they are authenticated or not required to authenticate.
- Add support for net blocks in the deny list of the cookie middleware processor, ala Unbound, otherwise the deny list is difficult to use beyond a few simple specific IP addresses.
- Improvements to the Stelline server test support needed by the Stelline cookies test:
  - Advance mock system time in the Stelline server tests.
  - Move Stelline server tests under src/ to permit #cfg(test) based swap out of real system time for mock system time.
  - Use the thread_local version of mock_instant to ensure parallel mock time dependent tests don't interfere with each other (such tests also use tokio::time which only works if they run in a single thread).
  - Set mock system time to start at zero for each Stelline server test (as expected by the cookies .rpl test script).
  - Pass the IP address of the test client to the server so that the cookies middleware can match it against its deny list.
2024-06-27 11:22:02 +02:00
Philip-NLnetLabsandGitHub 97bfa2c9f8 DNSSEC validator (#328)
This PR adds a DNSSEC validator.
2024-06-13 14:05:56 +02:00
Ximon EighteenandGitHub b5b411ee56 Add a queryable zone tree (#286)
This PR adds zonefile/parsed.rs, zonetree/ and related examples/, which
together enable, and show a library user how, to go from a zone file in
presentation format to an in-memory tree of zones which can be queried to
provide an answer, or walked (iterated over).

The tree also supports versioned write operations and a trait based zone
implementation allowing for the in-memory tree for a zone to instead be some
other (a)synchornous backing store (as demonstrated by the mysql-zone.rs
example).

The zonetree module is feature-gated behind the unstable-zonetree feature.
2024-04-12 10:21:21 +02:00
Ximon EighteenandGitHub 0bd1a68fe0 Add the net::server module. (#274)
This PR adds an unstable net::server module that enables the creation of UDP
and TCP DNS servers using base transport server, middleware and service building blocks.
2024-04-11 16:41:40 +02:00
Ximon EighteenandGitHub eb446cba54 Permit zone file strings upto AND including 255 characters in length. (#284)
This PR fixes a bug in the inplace zone parser that rejects character string of length 255.
2024-03-21 15:54:32 +01:00
Philip Homburg 4d13fe8998 Client Cache (#275)
This PR adds experimental support for a client cache provided as a pass
through transport
2024-03-12 10:32:21 +01:00
Philip-NLnetLabsandGitHub b8d2aa59bf Client Transport (#215)
This PR adds experimental support for client transport of DNS messages.

It also adds a new concept of unstable features which gate code that can introduce breaking changes also in non-breaking releases.
2024-01-15 14:54:20 +01:00
xofyargandGitHub c54c7f7874 Fix a bug in dname scanning (#240)
The PR fixes an issue in scanning absolute domain names from a zonefile.
2023-11-16 14:37:32 +01:00
Martin HoffmannandGitHub 500930e68d Fix scanning of the root name. (#210)
This PR fixes scanning (i.e., reading from presentation format) of domain
names that are just the root label. It also fixes how they are displayed:
previously they were empty, now they are displayed as a dot. It also adds a
new method Dname::fmt_with_dot that returns a placeholder type that displays
the name with a dot at the end.
2023-09-18 14:22:36 +02:00
Martin HoffmannandGitHub cd88889557 Redesign zone file parsing. (#142)
This commit completely redesigns zone file parsing. The primary change is to
convert the scanner into a trait in order to allow multiple zone parser
implementations for different sources and purposes. A number of changes had
to be made in order to make this possible.

The commit also contains an initial implementation of a scanner that modifies
data in-place and can thus returned parsed data with only a minimal amount
of additional allocations. While working, this scanner is more a
proof-of-concept at this point to ensure that the API design is sound.

This commit is based on ideas and code proposed by @not-my-profile in #106.

This commit increases the minimal supported Rust version to 1.59.0.
2022-11-07 15:11:36 +01:00
Martin Hoffmann 748a4d2dc8 Merge domain-resolv into domain::resolv. 2020-08-25 17:52:10 +02:00