Home > Security > The DNSSEC Diaries, Ch. 4: A Schema For TXT

The DNSSEC Diaries, Ch. 4: A Schema For TXT

Right.  Enough theory.  Lets get down to bits and bytes.  As of 1.02, the basic name/key mapping for http://www.hospital-link.org looks roughly like:

http://www.hospital-link.org IN TXT “v=key1 ha=sha1 h=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15”

Lets break this down:

  • http://www.hospital-link.org:  We’re attaching the key record directly
  • v=key1:  The subtype of this TXT record is key, version 1.
  • ha=sha1:  The hash algorithm used on the attached data is SHA-1.
  • h=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15:  When connecting to http://www.hospital-link.org, a certificate will be presented.  The hash of this certificate will be f1d2d2f924e986ac86fdf7b36c94bcdf32beec15, as per the hash algorithm declared in ha.

Yes, it really can be this easy.  One of the expensive aspects of X.509 was learning how to generate and maintain certificates.  Doing the above is much simpler.

Of course, that’s not allowed to be the end of the story.  What else might we put in there?

(Later, we’ll discuss the finer points of this particular grammar, effectively a space delimited flat key-value pair architecture.   There are other approaches, and I could be convinced to shift to them.  But this is what we’re using now, mainly for parity with most everything else using TXT.)

The power of DNSSEC is the ability to bootstrap trust.  There’s a very interesting technology out there called Strict-Transport-Security, that’s slowly being integrated into each browser.  Strict-Transport-Security, or STS, enforces the use of TLS when accessing web sites.  In effect, it turns off insecure HTTP.

In an era where hijacking HTTP sessions is as easy as burning sheep, this is a big deal.

STS has a problem — right now, use of it requires something of a “leap of faith” — the first time a site is connected to, there will be no STS bit to enforce that initial use being insecure. And there’s a second problem — once you’ve cached a value for STS, what if you’re wrong?    As my friend Damon Cortesi pointed out:

Just spent the past hour debugging what turned out to be HSTS – http://bit.ly/9on39S – This is why developers hate security!

Why should it be any harder to find out whether to use TLS, than it is to discover the IP to connect to?  Wouldn’t it be nice if you could ask via DNSSEC?

It would.  Thus, though Phreebird (Phreeload, really) isn’t really in a position to enforce STS, not being in the HTTP pipeline, KEY1 is explicitly supporting sts=1 as a way of securely expressing TLS only.  The idea has come up before, in Barth and Jackson’s ForceHTTPS, and it’s a good one.  We basically end up with the following in DNS:

http://www.hospital-link.org IN TXT “v=key1 ha=sha1 h=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 sts=1”

Is this enough?  I’m not sure.

Another thing I’m supporting is sn=1 — Marsh Ray did some pretty severe things against TLS a while back, and fixing them required a breaking change to the TLS protocol.  Right now, there’s no safe way to know if the host you’re communicating with has Marsh et al’s fix.   We can put a bit into this record saying Secure Negotiation is supported.

This does mean, by the way, that we’re mixing identity and policy.  I’m not convinced that’s a bad thing.  I am convinced that I don’t want to run a new query for each individual bit of policy that’s attached to a name.  It’s not necessarily slow — when you query TXT, you get all TXT records, as opposed to having to burn an RRTYPE on each policy bit — but it invites confusion attacks where it’s unclear which bits of policy apply to which representation of identity.  That, I am scared of.

But neither of the above tricks actually addresses key retrieval itself.  One case that I am intentionally supporting right now is that of the server farm which contains too many individual keys to place in DNS in advance.  By standard security theory, bits are cheap, so if you have a hundred TLS accelerators, you should never move one private key into all of them.  Instead, you should make a hundred different keys, and sign them all with the same Certificate Authority.  Well, a hundred private keys means a hundred public keys, and that’s too much for us.  Instead, I support something called Livehashing.  If “lh=1” shows up in the TXT KEY1 record, and the hash of the certificate is unrecognized, I’ll do a second lookup — this one, actually containing the hash of the witnessed cert.  So, for example, if I connect to http://www.hospital-link.org, get a certificate with the hash of e242ed3bffccdf271b7fbaf34ed72d089537b42f, and see:

http://www.hospital-link.org IN TXT “v=key1 ha=sha1 lh=1”

I will do a second lookup, for:

_keyhash-e242ed3bffccdf271b7fbaf34ed72d089537b42f.www.hospital-link.org

At present, if I get any secure record back from this name, I’ll assume that means the name and hash are acceptably linked.  A future release will have a better mechanism for confirmation.

Though this method adds a round trip, it significantly improves deployability for large sites.  That matters.  It also only adds that round trip in circumstances where the large site would otherwise be unable to deploy the technology, rather than slowing everyone down for the benefit of a few.  That matters even more.

It also causes issues with CNAMEs and Wildcards, as discussed in Ch. 1.  I think I know how to address that, though.

Another area of significant controversy is precisely what is stored in the DNS.  There’s basically the choice of the certificate vs. the public key, and whether the data is stored hashed or not.  Right now, I have an option called hr, for Hash Range.  If hr=cert, or is unset, then the thing to hash is the entire certificate.  If hr=pubkey, then the data to be hashed is simply the public key of the endpoint.

What’s the difference?  Ah, welcome to the weeds.  If one hashes the certificate, then the data asserted by DNSSEC includes all the policies embedded in X.509.  Important: That doesn’t mean you can necessarily trust said policies — in fact, there are policies that we know we can’t trust when exclusively asserted by DNSSEC, like EV — but the semantics are at least there to continue supporting them.

However, if one hashes the public key, that means an implementation doesn’t need to support X.509, or even ASN.1 at all.  That’s potentially a significant reduction in complexity.

So, that’s what we have now as optional settings:  sts=[0|1], sn=[0|1], lh=[0|1], and hr=[cert|pubkey].

What’s coming soon, or at least being considered?  We’ll talk about that in the next post.

Categories: Security
  1. December 19, 2010 at 9:23 pm

    You wrote:

    “However, if one hashes the public key, that means an implementation doesn’t need to support X.509, or even ASN.1 at all. That’s potentially a significant reduction in complexity.

    So, that’s what we have now as optional settings: sts=[0|1], sn=[0|1], lh=[0|1], and hr=[cert|pubkey].”

    Well, that’s not exactly true. If you’re letting hr=cert _or_ pubkey, then if the client implementation wants to actually _work_, then it’d damn well better do x509 or it’s only going to work with whatever percentage uses hr=pubkey.

    What are the benefits of having hr=cert as an option? Why is that even a knob? (It’s possible I’m missing something, but what is a cert but a signed key hash? Let the DNS record be the cert.)

    • December 19, 2010 at 9:33 pm

      Nevermind, got it on the re-read: the policy variables set in the cert.

    • December 19, 2010 at 9:36 pm

      Jeffrey,

      Think about protocols other than TLS — should you have to implement an entire ASN.1 stack, to get the pubkey of your destination?

      A cert is a huge pile of other stuff besides a pubkey. More importantly, it’s not just a hash of the pubkey, it’s the actual thing. We’ve seen more than a few attempts to put full certs in DNS…they seem to fail, and are quickly replaced with cert hashes.

  2. Paul wouters
    December 20, 2010 at 6:38 am

    too bad your txt does not state anything about other protocols or ports and assumes only https. if one other protocol is added you need to change format and parse through multiple txt records. draft for HASTLS addresses that shortcoming

    • December 20, 2010 at 6:47 am

      It’s actually an interesting question, whether or not keys should be tied to protocol or port. You’ll note that X.509 Subject Names very specifically declare neither, with the only component validated being the domain name.

      If you want to use the same certificate for TLS or IPSec, there’s nothing blocking that. I’m not at all convinced this is a bad idea.

      What we know is dangerous is spreading the same bits across cryptosystems — for example, if the same actual key is accidentally used for RSA and DSA. But using the same identity across application layer protocols? Infinitely less concerning. I mean, it’s status quo.

      There are interesting questions about cross-protocol, especially when you start thinking about — can you satisfy STS with anything other than TLS? Should you be able to express available protocols for satisfying security? Is this an appropriate place to declare crypto constraints? In other words, if you want to play the layering game, this is actually a fairly deep rabbit hole.

      I’ll definitely put this on the stack of things to write a diary about.

      (Hope this is helpful!)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: