Security/DNSSEC-TLS

From MozillaWiki
Jump to navigation Jump to search

This set of pages documents the TLS domain validation through DNSSEC project. This document is currently a work in progress. There are likely many errors.

Goal

Implement domain validation for TLS connections using DNSSEC in Firefox. That is, in addition to sending a certificate in the TLS handshake, a server would send sufficient DNSSEC records to convince the client of its identity and establish public key material.

Background

TLS sessions require a chain of trust to authenticate the server to the client. Currently this is achieved through a series of PKIX certificates that link the server's certificate to a trusted root certificate stored in by the client. Trusted root certificates are issued by Certificate Authorities. Currently, nothing prevents any authority from signing a certificate for any domain name.

DNSSEC is a method of authenticating DNS records that also uses a chain of trust. In the case of DNSSEC, the trust structure is identical to the DNS hierarchy. For example, only the entity in charge of .com can sign the record that authenticates example.com, and only the (single) entity in charge of the (single) root can sign the record that authenticates .com.

To validate a DNS record, its RRSIG record and corresponding DNSKEY must be obtained. If the signature checks out (using the key), then the key record must be checked (recursively). This process eventually arrives at a key signing key for a given level in the DNS hierarchy. To go up the hierarchy, the DS record for the level must be authenticated by a DNSKEY in the next level up. If that succeeds, then the process continues (i.e. the DNSKEY in the next level up must be authenticated, and so forth). Eventually the root of trust is arrived at, whereupon the original DNS record has been validated.

DANE, CAA (Certification Authority Authorization), and CERT records are all methods of embedding certificate information in DNS records. With DANE, either the public key or entire certificate (or the hash thereof) may be put in a TLSA record that specifies, for example, the certificate or public key to be used for connecting to example.com tcp port 443 (in the record _443._tcp.example.com). CAA uses the hash of the certificate and specifies that any certificate issued for (for example) example.com must be rooted by the hashed certificate. CAA uses TYPE257 records. CAA has other policy options, as well. CERT simply embeds a certificate in a DNS record. For the time being, while CAA is powerful, it has been determined to be too complicated for this use case. Furthermore, CERT can only specify whole certificates, not just public keys, and is thus too restrictive. Thus, DANE alone will initially be supported.

To use DNSSEC to perform domain validation, a key or certificate must be put in a DANE record corresponding to the server to validate. Then, during the TLS handshake, the chain of DNSSEC records from that record to an agreed-upon root must be sent along with the server certificate. The client can walk this chain of records to a trusted root to validate the material. If this succeeds, the client then uses either the embedded key material or the key material in the server certificate (that hast just been validated by the DNSSEC chain) as the public key for a key exchange. Note that if the DANE record consists of an entire certificate and that certificate will always be sent in the TLS handshake, the DANE record itself may be omitted. In this case, the RRSIG record for the DANE record will have to be used to validate the certificate sent in TLS.

Obviously this mechanism could work out of band. That is, instead of embedding the DNSSEC chain in the TLS handshake, the client could perform simultaneous DNSSEC lookups to verify the material in the server certificate. However, this would be significantly slower as it would involve multiple round-trip communications with another server.

This mechanism does not require the involvement of a certificate authority. A server can issue a self-signed certificate and bind that certificate to a DANE record (either by key, whole certificate, or hash of either). Then, provided there exists a valid DNSSEC chain back to the root of trust, the self-signed certificate will be authenticated by that chain in the TLS handshake.

Alternatively, a server can use a certificate issued by a CA. In this case both the certificate chain and the DNSSEC chain must be valid.

This mechanism prevents CAs mis-issuing certificates. If a CA issues a certificate it was not supposed to, and that certificate gets used, it will not match the contents of the DANE/CAA record. Of course, the server with the bad certificate could simply omit the DNSSEC chain, so if none is sent, perhaps we should perform the out of band DNSSEC chain verification ourselves.

Verifying a DNSSEC Chain

Verification of a DNSSEC chain can be started from the bottom up. For instance, to verify the A record for wiki.mozilla.org, the process can be started by requesting the A and RRSIG records for wiki.mozilla.org, as well as the DNSKEY records for mozilla.org (where mozilla.org is from whence we got the authoritative records for wiki.mozilla.org). One of the zone-signing DNSKEYs will verify the signature on the RRSIG (if all is well). The DNSKEY records then must be verified by the key-signing DNSKEY(s) for mozilla.org. At this point, to establish trust up to the root, a DS record from .org to mozilla.org must be verified. This requires the DNSKEYs from .org. Once the DS record checks out, the process recurses: .org's DNSKEYs are walked up to the DS record for .org, which leads to the root: .

At this point, since our root keys are the root of trust, if the .org DS record is verified, the entire chain has been verified. In the simplest case, this process requires the A and RRSIG records from wiki.mozilla.org, one zone-signing DNSKEY and corresponding RRSIG record for mozilla.org, one keys-igning DNSKEY and corresponding RRSIG record for mozilla.org, a DS record and corresponding RRSIG record for mozilla.org (from .org), a zone-signing DNSKEY and corresponding RRSIG record for .org, a key-signing DNSKEY and corresponding RRSIG record for .org, a DS record and corresponding RRSIG record for .org, and a copy of the root DNSKEYs. Thus 14 records would be required in a full DNSSEC chain.

In theory, it should not be necessary to have both a zone-signing key and a key-signing key for each level of the hierarchy. In practice, though, both are used (and sometimes multiples of each are used). In an example verification of wiki.mozilla.org, 22 records were sent for a total of 3832 bytes.

In theory, the DNSKEYs of TLDs could be cached by the client, meaning only everything up to the DS and corresponding RRSIG for mozilla.org need be sent. This could limit the number of records to 8 in normal operation (using ZSKs and KSKs). This could operate as follows:

  1. Verify wiki.mozilla.org A record using mozilla.org ZSK (requires the A and corresponding RRSIG records and the ZSK DNSKEY record)
  1. Verify ZSK from step 1 using KSK (requires in addition a DNSKEY record and the RRSIG record for the ZSK).
  1. Verify the KSK using mozilla.org's DS record (requires in addition the DS and corresponding RRSIG record, as well as the cached .org DNSKEY (and the RRSIG for the KSK, I think))

From there, we have already verified .org, so wiki.mozilla.org has been verified using a total of 8 transmitted records. From the trace, this reduces the data sent from 3832 to 1280 bytes. The amount of data required will vary by site (by domain name), but it will probably be in the range of 1K. Note: the TLS server hello from wiki.mozilla.org is 1063 bytes (sent in 1 packet). Adding the 1K of DNSSEC messages to this would fit in 1 more packet.

(Aside: CNAME records do not work well with this porposal. For instance, the A record for addons.mozilla.org is actually a CNAME for amo.glb.mozilla.net. The first problem is that amo.glb.mozilla.net has no RRSIG record, and thus cannot actually be verified through DNSSEC. The second problem is even if it did, we would have to send twice as much (more? can CNAMES point to CNAMES?) data.)

Goals

Goals

Primary

  • asdf
    • asdf
      1. asdf


Secondary

  • foo
    • foo
      • Note: foo

Compatibility