DNSSEC is the (not so) new technology that will finally fix the trust problems inherent in the DNS, making spoofing and forging much harder or impossible. Or at least, that's what everyone hopes.
Unfortunately, although the idea behind the technology is simple (it basically boils down to using well-known public key cryptography techniques to verify signatures attached to DNS replies), the details are scaringly complex, and comprehension is not helped by the fact that the final specification in use today was changed a few times since the first proposal.
Without having to set up a real DNS server, it's possible to observe the verification process by using only the dig utility. As the man page reminds, to use it for DNSSEC validation, dig must have been built with the -DDIG_SIGCHASE option. Luckily, all the major distributions seem to have a DNSSEC-enabled dig.
The example here will verify the A record for the domain name www.eurid.eu. But really, this is just a more-or-less randomly picked example; as more and more TLD are being signed, it should be possible to verify any name that has a trust of chain up to the root. For more information on the status of which TLD domains are signed, this ICANN page provides up-to-date information. As shown there, the eu. TLD is signed and has DS records in the root, as do many others. At the time of this writing, the net. and com. zones are scheduled to be signed in the first months of 2011. That will probably be the time when DNSSEC really starts to take off.
Root keys
Before starting, dig needs to be given a trust anchor (which is a fancy name for one or more keys that are trusted by definition and do not need to be verified further. The role of these keys is similar to the root SSL certificates installed in the browser: when something is signed with them, the verification ends successfully).
The perfect keys to use (and, in an ideal world where DNSSEC is fully deployed, the only needed) are the root keys, that is, the keys found in the "." zone. Since in DNSSEC keys are stored in DNSKEY records, here's how to download them with dig:
$ dig . DNSKEY | grep -Ev '^($|;)' > root.keys # check $ cat root.keys . 86352 IN DNSKEY 256 3 8 AwEAAcAPhPM4CQHqg6hZ49y2P3IdKZuF44QNCc50vjATD7W+je4va6dj Y5JpnNP0pIohKNYiCFap/b4Y9jjJGSOkOfkfBR8neI7X5LisMEGUjwRc rG8J9UYP1S1unTNqRcWyDYFH2q3KnIO08zImh5DiFt8yfCdKoqZUN1du p5hy0UWz . 86352 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
Here is a clearer query that shows the root keys with their tags:
$ dig +multiline . DNSKEY ; <<>> DiG 9.7.2-P2 <<>> +multiline . DNSKEY ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53322 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;. IN DNSKEY ;; ANSWER SECTION: . 86400 IN DNSKEY 256 3 8 ( AwEAAcAPhPM4CQHqg6hZ49y2P3IdKZuF44QNCc50vjAT D7W+je4va6djY5JpnNP0pIohKNYiCFap/b4Y9jjJGSOk OfkfBR8neI7X5LisMEGUjwRcrG8J9UYP1S1unTNqRcWy DYFH2q3KnIO08zImh5DiFt8yfCdKoqZUN1dup5hy0UWz ) ; key id = 40288 . 86400 IN DNSKEY 257 3 8 ( AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh /RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWA JQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXp oY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3 LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGO Yl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGc LmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0= ) ; key id = 19036 ;; Query time: 109 msec ;; SERVER: 172.27.20.21#53(172.27.20.21) ;; WHEN: Mon Nov 15 23:41:59 2010 ;; MSG SIZE rcvd: 439
Here we see that the root keys that we put in the trusted keys file have id 40288 and 19036. This will become important later.
(Note: strictly speaking, only the key with id 19036 - the KSK - is necessary, because that's the one that ultimately signs the root DNSKEY RRset, but having both can't hurt.)
Getting the root keys using dig is good enough for this example; in practice, serious validating resolvers will obtain the keys in a secure way, or the keys will come bundled with the software, similar to the built-in SSL root certificates that are bundled with browsers.
Obviously since the keys are rolled periodically, the keys above will not be valid for long, and will need to be downloaded again if the experiment is to be repeated in the future. The key numbers shown here are those in effect at the time of writing, and will make no sense at all in some weeks, when the keys are rolled.
Also note that for this and the following commands the DNS server used by dig (ie, the one found in
Bottom-up verification
As said, let's verify the A record for www.eurid.eu (line numbers in the output added for the following explanation):
$ dig +sigchase +trusted-key=./root.keys www.eurid.eu. A | cat -n 1 ;; RRset to chase: 2 www.eurid.eu. 558 IN A 195.234.53.204 3 4 5 ;; RRSIG of the RRset to chase: 6 www.eurid.eu. 558 IN RRSIG A 7 3 600 20101201125038 20101101115329 62990 eurid.eu. cq4Sh8HJkFt1VPM/p+1IGEvwMiw9KRG+2GPnfCvquJNfKioB+MpV21E8 h7uV25V/kndXGEh+r27FRBCmsMAftdcrTtB+5NCwcfP17LKOxvDc3Mg1 p4UvVjMK//xiT+yJoM61qsLLbbfFEoCYtz0fZee4Hf7FLlvyYtXNXQG9 P34= 7 8 9 10 Launch a query to find a RRset of type DNSKEY for zone: eurid.eu. 11 12 ;; DNSKEYset that signs the RRset to chase: 13 eurid.eu. 86366 IN DNSKEY 257 3 7 AwEAAbu3N0HTlocsABTY4SmW5Et6kAwa1BHg2Jmjcy87VIvKrubLCjeO FLbC2hklqnlZvlyUI5DzmS3YW/1iGNQJ+u9Rdv63BWq1HPCimkxJasSQ vIff1zTYDujCucJgnn5Y3nVnJYaRvn3pmaQYmVA4jL/b3vuOmCI1jNxU NKnfxYXntYBEvfU2C824Bsv+ngKwAVIW/+3dtDhCsHfYzN8lIRHXR9yi G3/sLvFUDUH4n9qIwYGFQ00Kiv/j35VGWwruLS2nj98tw2zEgKg9otcu natVSltUnajuauaTamSTDU/cKk45QHumbQxqxQ6CMv3irDsfVYh85tUe MtiXTb4Sn7s= 14 eurid.eu. 86366 IN DNSKEY 256 3 7 AwEAAecbZhciFc12GqKd3NSd40FpZ4PyXwfvnQ7makOUaY+McBWnkK6h j/6TvR+/UafBjxPcL6Dmv9UG+FFdiJJtoukC7IapbPkquA8ItnQrJp0R xWAAkJq5MlftKUAJfZGUgSlRHc6UBCHGjrJnf2QHN/NIFz5BzSPrhLiP 1/2wbDEF 15 16 17 ;; RRSIG of the DNSKEYset that signs the RRset to chase: 18 eurid.eu. 86366 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 34023 eurid.eu. TNQhHOH+TdsOzWglBBOUL5gUM7oHZbeFBis9e3PbDXN+wsD2yrOwek2A XczHFrtWoQp6i3eDWOvLwF4DltAjCiVKU+oPAbTJLnVldhWKA4Q+loK2 hl9NE8Txf8lUdRnSlqnewxkbdh3Ml7zUfPgKYWpYxd6/oE6SvOGLvNB5 i6y2lIXqgNyIwd7xL7Y1d+Jvto3U308c/jcws3xWvGkKVoqDBTH3+aaL n+g7VzcnKKusSAPr/aG+LBjXcnL46kWsPnSafFU4Qnw0V+ls8CpL0do7 TbGLVNWu5NVTLCC92orTIYOPRigV/Yg2f+hIiQiwoMIJssJQBQ8drCB+ yc01lg== 19 eurid.eu. 86366 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 62990 eurid.eu. CdldAM01iqI684Cwe2AF6ZDh4J8ODkbM9Cey+1jUMbAgnORW/WONAUMl 7DFOzchltbBo/5s7kqzoBMUEp8P41dkuLancH9/dHI7pUUNnzprdFFQV 9G+4gIwD3as4og17oX+b1gkf8VyYx8qBEDtIxT9DPHYZ1FwUTX2mBlNf zck= 20 21 22 23 Launch a query to find a RRset of type DS for zone: eurid.eu. 24 25 ;; DSset of the DNSKEYset 26 eurid.eu. 86366 IN DS 34023 7 1 C0C4ABA58090643AE17BA8493C4AD2295D4D1376 27 28 29 ;; RRSIG of the DSset of the DNSKEYset 30 eurid.eu. 86366 IN RRSIG DS 7 2 86400 20101122031929 20101115023628 37319 eu. rPrB+fdy1/oBoDosNKQhvVrTI3VeOkYVcNZgthsqt7DwlWNJ5NrRKfnF KbVzuiMpAHCBT+dWb9SRimBqCYGHHxSXym6gkWlAA0qJLV9HHqKZ7RF8 Ogro4mrknmxIKjgh/SNWZ4u9AN7rzeA9vuJHeYV6S3UefQMlSh9Par2Y WeE= 31 32 33 34 35 ;; WE HAVE MATERIAL, WE NOW DO VALIDATION 36 ;; VERIFYING A RRset for www.eurid.eu. with DNSKEY:62990: success 37 ;; OK We found DNSKEY (or more) to validate the RRset 38 ;; Now, we are going to validate this DNSKEY by the DS 39 ;; OK a DS valids a DNSKEY in the RRset 40 ;; Now verify that this DNSKEY validates the DNSKEY RRset 41 ;; VERIFYING DNSKEY RRset for eurid.eu. with DNSKEY:34023: success 42 ;; OK this DNSKEY (validated by the DS) validates the RRset of the DNSKEYs, thus the DNSKEY validates the RRset 43 ;; Now, we want to validate the DS : recursive call 44 45 46 Launch a query to find a RRset of type DNSKEY for zone: eu. 47 48 ;; DNSKEYset that signs the RRset to chase: 49 eu. 86366 IN DNSKEY 257 3 7 AwEAAc8eyl1THSdL4ZHXK4i5q7OfkxnbY6pA3vzs1O4CeF8wkR5yIHmd xhXfP17uIj73Fpr4ZU+5mK4N3vmJKtWV0ML3ieO1bXvPpuNEEvXmkNOK EUSAfnk9CT8AlS5jiJz6hpzkYd6OFIrnQVgIqGWOqRdx+1sMXBO+IuKh gvYLunsSZyBTWftiHy11NeGMNPA4QO4fcS/IgJIjvpYtr0lhlmwiyS5k c6fz8CD1YmiSzIAIcrqBfOi6/VCarEFxZsEhRi+UFp3ipUz6s8zZ+T8x lDxgRyScApiudiZKor/omLn+JUo4hAaJFo0R2EbnZY7hiK71DkTA2yY+ 3VKuizDV0Kk= 50 eu. 86366 IN DNSKEY 256 3 7 AwEAAb7UvT6q/qhscgKJPNDxrnB0Y8mMUqWMD1E69J4vzBc6dqKMckyC H49Sq//3+5mVBshLV3EZORl5guWDIcwJtWeGIgpzRjqDIgkJrDy4mPq1 4qv4mR3gvpsEKCKdSTR8FH+rcKd3aB7SYQLaNF2gqaZloAqjMBnffVd2 xlc4bWVP 51 52 53 ;; RRSIG of the DNSKEYset that signs the RRset to chase: 54 eu. 86366 IN RRSIG DNSKEY 7 1 86400 20101119124925 20101112114925 37319 eu. vafh1utSPWOs4EZ9OS0KCeZxxTJEPge+LTjcdR9aQUcxdqVHceqr48RK mKuwi6U+qzZ0mXYz06V3Gn2apqayWOxNg/geIVf+5DsKNwkgaaHr1zHi sCxKcLikSevxTH2g3PwbAq1PBPillnNpmasKUwJ97MRyhTT0kj9wUx56 tUs= 55 eu. 86366 IN RRSIG DNSKEY 7 1 86400 20101119124925 20101112114925 61179 eu. UrsoJdsyKuxhClgR8IiRN5iq/IDrOp5ElZ9PKyA0wULZD3aQtHB4USSB t4fJzgN6KbaCBwBSSsG0eWi5U+krquvkzGxqlYJD+9+Gtm4HlZpxATQ5 2rIytsR+vtCmeu2YrC42lGa4iF0oQ2rfzQvonGezWtdPUDI6Z9VdLeFu muw3BQO87NIrWF00VaVVXZotdwRFH7EA29v7snbLL5BpSaiSBlGCALhk 2dEleVbg8YcKTg/cgr2fasHrN0lGc2Dv8l5Ph2U6GMIb2DBAC22RqYk8 HhrbTXDacgbMVtcYIBprQ9JN6jZSXxmzl5RDedeoUQJgRR7QQ4cOiRYZ MUJm4g== 56 57 58 59 Launch a query to find a RRset of type DS for zone: eu. 60 61 ;; DSset of the DNSKEYset 62 eu. 58008 IN DS 61179 7 1 87E2B3544884B45F36A0DA72DADCB0239C4D73D4 63 eu. 58008 IN DS 61179 7 2 3B526BCC354AE085AD9984C9BE73D271411023EFF421EF184BCE41AC E3DE9F8B 64 65 66 ;; RRSIG of the DSset of the DNSKEYset 67 eu. 58008 IN RRSIG DS 8 1 86400 20101122000000 20101114230000 40288 . oePYMoFkBkYf7fh2hLam99KyzlRddeh1zsIGtrfk30u074wP3Z2WdLUm FPF8LbNXLAAIo+XtKYH4LK8h36L44FhEtBoS2GL4GGIZasenjBHMEDx0 z6A3+lOED50djuoOBWCsRenS54KHXrNJ8cTS9D/Yg60/GMToMHLyAYUJ eMU= 68 69 70 71 72 ;; WE HAVE MATERIAL, WE NOW DO VALIDATION 73 ;; VERIFYING DS RRset for eurid.eu. with DNSKEY:37319: success 74 ;; OK We found DNSKEY (or more) to validate the RRset 75 ;; Now, we are going to validate this DNSKEY by the DS 76 ;; OK a DS valids a DNSKEY in the RRset 77 ;; Now verify that this DNSKEY validates the DNSKEY RRset 78 ;; VERIFYING DNSKEY RRset for eu. with DNSKEY:61179: success 79 ;; OK this DNSKEY (validated by the DS) validates the RRset of the DNSKEYs, thus the DNSKEY validates the RRset 80 ;; Now, we want to validate the DS : recursive call 81 82 83 Launch a query to find a RRset of type DNSKEY for zone: . 84 85 ;; DNSKEYset that signs the RRset to chase: 86 . 86093 IN DNSKEY 256 3 8 AwEAAcAPhPM4CQHqg6hZ49y2P3IdKZuF44QNCc50vjATD7W+je4va6dj Y5JpnNP0pIohKNYiCFap/b4Y9jjJGSOkOfkfBR8neI7X5LisMEGUjwRc rG8J9UYP1S1unTNqRcWyDYFH2q3KnIO08zImh5DiFt8yfCdKoqZUN1du p5hy0UWz 87 . 86093 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0= 88 89 90 ;; RRSIG of the DNSKEYset that signs the RRset to chase: 91 . 86093 IN RRSIG DNSKEY 8 0 86400 20101124235959 20101110000000 19036 . SmZKqR1XNc73PUkVI6YRlXwcxeLfUmvLpikKaxTg+HmYCyWrmxzmYv/1 onFpCl8EZ75sGwIM78QCIekH+V1Azoc29fOx/NyWh86wc4bUqouoLXCH 99rEz2024pu8ZaC7ly1/HO+SCCV0ALT03/UvdwloEBl60bqBXZvN44K7 RIBqeLFOdXMHa5G8dNlopZaKsV5+0CGD28CgkC07A5//sumpEzGDmeq2 9gAGHk4WIpBL2EzUtToJRfdygpelA4akf+c32PkQGEEkjeDCEi1XCiwn lTCBiGrDAqYW5ivUb26h0twVH7vJlDWCR57/Q7SroV4oljK1tXkSL8bL 9beusw== 92 93 94 95 Launch a query to find a RRset of type DS for zone: . 96 ;; NO ANSWERS: no more 97 98 ;; WARNING There is no DS for the zone: . 99 100 101 102 ;; WE HAVE MATERIAL, WE NOW DO VALIDATION 103 ;; VERIFYING DS RRset for eu. with DNSKEY:40288: success 104 ;; OK We found DNSKEY (or more) to validate the RRset 105 ;; Ok, find a Trusted Key in the DNSKEY RRset: 40288 106 ;; Ok, find a Trusted Key in the DNSKEY RRset: 19036 107 ;; VERIFYING DNSKEY RRset for . with DNSKEY:19036: success 108 109 ;; Ok this DNSKEY is a Trusted Key, DNSSEC validation is ok: SUCCESS 110
Good, the verification succeeded. But what happened? Let's go through the steps.
First, the RRset that needs to be verified is identified (a single item RRset here): quite obviously, that is (line 2)
www.eurid.eu. 558 IN A 195.234.53.204
The signature for that record is given in line 6:
www.eurid.eu. 558 IN RRSIG A 7 3 600 20101201125038 20101101115329 62990 eurid.eu. cq4Sh8HJkFt1VPM/p+1IGEvwMiw9KRG+2GPnfCvquJNfKioB+MpV21E8 h7uV25V/kndXGEh+r27FRBCmsMAftdcrTtB+5NCwcfP17LKOxvDc3Mg1 p4UvVjMK//xiT+yJoM61qsLLbbfFEoCYtz0fZee4Hf7FLlvyYtXNXQG9 P34=
The interesting part of the signature is that it was created using the key with tag 62990, and the signer name is eurid.eu. (this will be useful in a second).
Since signatures are created using a private key, to verify the signature we need to have the corresponding public key, and that's what dig requests and shows in lines 13 and 14:
eurid.eu. 86366 IN DNSKEY 257 3 7 AwEAAbu3N0HTlocsABTY4SmW5Et6kAwa1BHg2Jmjcy87VIvKrubLCjeO FLbC2hklqnlZvlyUI5DzmS3YW/1iGNQJ+u9Rdv63BWq1HPCimkxJasSQ vIff1zTYDujCucJgnn5Y3nVnJYaRvn3pmaQYmVA4jL/b3vuOmCI1jNxU NKnfxYXntYBEvfU2C824Bsv+ngKwAVIW/+3dtDhCsHfYzN8lIRHXR9yi G3/sLvFUDUH4n9qIwYGFQ00Kiv/j35VGWwruLS2nj98tw2zEgKg9otcu natVSltUnajuauaTamSTDU/cKk45QHumbQxqxQ6CMv3irDsfVYh85tUe MtiXTb4Sn7s= eurid.eu. 86366 IN DNSKEY 256 3 7 AwEAAecbZhciFc12GqKd3NSd40FpZ4PyXwfvnQ7makOUaY+McBWnkK6h j/6TvR+/UafBjxPcL6Dmv9UG+FFdiJJtoukC7IapbPkquA8ItnQrJp0R xWAAkJq5MlftKUAJfZGUgSlRHc6UBCHGjrJnf2QHN/NIFz5BzSPrhLiP 1/2wbDEF
Of these two keys, the first is a so-called Key Signing Key (KSK), and the second is a Zone Signing Key (ZSK). This is encoded in the fifth field: in that value, bit 0 is called the SEP (Secure Entry Point) and is set for the KSK, and not set for the ZSK (hence they usually have the two values 257 and 256 respectively). As a related note, the KSK is longer than the ZSK; this is usually the case, because the KSK is rolled less frequently (as changing it needs to involve the parent zone, while rolling the ZSK can be done independently and thus more often).
Although dig doesn't show the tags above, the KSK has tag 34023, and the ZSK has tag 62990. To check that, we can run something like this:
$ dig +multiline eurid.eu. DNSKEY ; <<>> DiG 9.7.2-P2 <<>> +multiline eurid.eu. DNSKEY ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36198 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;eurid.eu. IN DNSKEY ;; ANSWER SECTION: eurid.eu. 86400 IN DNSKEY 257 3 7 ( AwEAAbu3N0HTlocsABTY4SmW5Et6kAwa1BHg2Jmjcy87 VIvKrubLCjeOFLbC2hklqnlZvlyUI5DzmS3YW/1iGNQJ +u9Rdv63BWq1HPCimkxJasSQvIff1zTYDujCucJgnn5Y 3nVnJYaRvn3pmaQYmVA4jL/b3vuOmCI1jNxUNKnfxYXn tYBEvfU2C824Bsv+ngKwAVIW/+3dtDhCsHfYzN8lIRHX R9yiG3/sLvFUDUH4n9qIwYGFQ00Kiv/j35VGWwruLS2n j98tw2zEgKg9otcunatVSltUnajuauaTamSTDU/cKk45 QHumbQxqxQ6CMv3irDsfVYh85tUeMtiXTb4Sn7s= ) ; key id = 34023 eurid.eu. 86400 IN DNSKEY 256 3 7 ( AwEAAecbZhciFc12GqKd3NSd40FpZ4PyXwfvnQ7makOU aY+McBWnkK6hj/6TvR+/UafBjxPcL6Dmv9UG+FFdiJJt oukC7IapbPkquA8ItnQrJp0RxWAAkJq5MlftKUAJfZGU gSlRHc6UBCHGjrJnf2QHN/NIFz5BzSPrhLiP1/2wbDEF ) ; key id = 62990 ;; Query time: 42 msec ;; SERVER: 172.27.20.21#53(172.27.20.21) ;; WHEN: Tue Nov 16 21:04:17 2010 ;; MSG SIZE rcvd: 450
So, as expected, our signature on the A record was created with the ZSK (normally the KSK is only used to sign DNSKEY RRsets, although DNSSEC does not enforce that), tag 62990. So far so good.
But then, the DNSKEY records are themselves a RRset, and, like any other RRset, that has to be signed. We are walking the trust of chain: to verify the A record, we must verify its signature; to verify that signature, we need to have the public key that created it; that key is part of a RRset, and to verify it we need to verify its signature (and we're not done yet). That signature is exactly what we find in lines 18 and 19:
eurid.eu. 86366 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 34023 eurid.eu. TNQhHOH+TdsOzWglBBOUL5gUM7oHZbeFBis9e3PbDXN+wsD2yrOwek2A XczHFrtWoQp6i3eDWOvLwF4DltAjCiVKU+oPAbTJLnVldhWKA4Q+loK2 hl9NE8Txf8lUdRnSlqnewxkbdh3Ml7zUfPgKYWpYxd6/oE6SvOGLvNB5 i6y2lIXqgNyIwd7xL7Y1d+Jvto3U308c/jcws3xWvGkKVoqDBTH3+aaL n+g7VzcnKKusSAPr/aG+LBjXcnL46kWsPnSafFU4Qnw0V+ls8CpL0do7 TbGLVNWu5NVTLCC92orTIYOPRigV/Yg2f+hIiQiwoMIJssJQBQ8drCB+ yc01lg== eurid.eu. 86366 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 62990 eurid.eu. CdldAM01iqI684Cwe2AF6ZDh4J8ODkbM9Cey+1jUMbAgnORW/WONAUMl 7DFOzchltbBo/5s7kqzoBMUEp8P41dkuLancH9/dHI7pUUNnzprdFFQV 9G+4gIwD3as4og17oX+b1gkf8VyYx8qBEDtIxT9DPHYZ1FwUTX2mBlNf zck=
We have two signatures here. One was created using the key with tag 34023 (the KSK), and the other was created using the key with tag 62990 (the ZSK). Both are signatures of the DNSKEY RRset; this RRset is, effectively, self-signed. How can we proceed further in the verification then? We need to have something in the parent zone (eu. here) that links into the eurid.eu. zone and allows us to climb further up in the chain of trust towards the root.
That "something" is called a DS record, which essentially is a cryptographic hash of the child zone's KSK, signed by the parent zone (ie, with the parent zone's key); if we trust the parent zone (we don't yet; we're still climbing the chain), we can then trust the KSK in the child zone. The DS record is shown in line 26:
eurid.eu. 86366 IN DS 34023 7 1 C0C4ABA58090643AE17BA8493C4AD2295D4D1376
This record comes from the eu. zone, the parent of eurid.eu. As the fifth field shows, this is a hash of the child zone's KSK (tag 34023), which we encountered previously.
I said earlier that the DS record is signed (it must be, to be any good); and indeed, line 30 has the signature:
eurid.eu. 86366 IN RRSIG DS 7 2 86400 20101122031929 20101115023628 37319 eu. rPrB+fdy1/oBoDosNKQhvVrTI3VeOkYVcNZgthsqt7DwlWNJ5NrRKfnF KbVzuiMpAHCBT+dWb9SRimBqCYGHHxSXym6gkWlAA0qJLV9HHqKZ7RF8 Ogro4mrknmxIKjgh/SNWZ4u9AN7rzeA9vuJHeYV6S3UefQMlSh9Par2Y WeE=
This tells us that the signature was generated with the key with tag 37319 and the signer name is eu. . Let's see:
$ $ dig +multiline eu. DNSKEY ; <<>> DiG 9.7.2-P2 <<>> +multiline eu. DNSKEY ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42913 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;eu. IN DNSKEY ;; ANSWER SECTION: eu. 86400 IN DNSKEY 256 3 7 ( AwEAAb7UvT6q/qhscgKJPNDxrnB0Y8mMUqWMD1E69J4v zBc6dqKMckyCH49Sq//3+5mVBshLV3EZORl5guWDIcwJ tWeGIgpzRjqDIgkJrDy4mPq14qv4mR3gvpsEKCKdSTR8 FH+rcKd3aB7SYQLaNF2gqaZloAqjMBnffVd2xlc4bWVP ) ; key id = 37319 eu. 86400 IN DNSKEY 257 3 7 ( AwEAAc8eyl1THSdL4ZHXK4i5q7OfkxnbY6pA3vzs1O4C eF8wkR5yIHmdxhXfP17uIj73Fpr4ZU+5mK4N3vmJKtWV 0ML3ieO1bXvPpuNEEvXmkNOKEUSAfnk9CT8AlS5jiJz6 hpzkYd6OFIrnQVgIqGWOqRdx+1sMXBO+IuKhgvYLunsS ZyBTWftiHy11NeGMNPA4QO4fcS/IgJIjvpYtr0lhlmwi yS5kc6fz8CD1YmiSzIAIcrqBfOi6/VCarEFxZsEhRi+U Fp3ipUz6s8zZ+T8xlDxgRyScApiudiZKor/omLn+JUo4 hAaJFo0R2EbnZY7hiK71DkTA2yY+3VKuizDV0Kk= ) ; key id = 61179 ;; Query time: 128 msec ;; SERVER: 172.27.20.21#53(172.27.20.21) ;; WHEN: Tue Nov 16 21:14:16 2010 ;; MSG SIZE rcvd: 444
Sure enough, the ZSK with tag 37319 is there.
At this point, dig has enough data to perform the first round of verifications (lines 35-43), which is successful. But we're not done yet: to verify the signature on the DS, we need to trust the key that was used to generate that signature (ie, key 37319). So dig goes out again and fetches the DNSKEY RRset for eu. (lines 49-50):
eu. 86366 IN DNSKEY 257 3 7 AwEAAc8eyl1THSdL4ZHXK4i5q7OfkxnbY6pA3vzs1O4CeF8wkR5yIHmd xhXfP17uIj73Fpr4ZU+5mK4N3vmJKtWV0ML3ieO1bXvPpuNEEvXmkNOK EUSAfnk9CT8AlS5jiJz6hpzkYd6OFIrnQVgIqGWOqRdx+1sMXBO+IuKh gvYLunsSZyBTWftiHy11NeGMNPA4QO4fcS/IgJIjvpYtr0lhlmwiyS5k c6fz8CD1YmiSzIAIcrqBfOi6/VCarEFxZsEhRi+UFp3ipUz6s8zZ+T8x lDxgRyScApiudiZKor/omLn+JUo4hAaJFo0R2EbnZY7hiK71DkTA2yY+ 3VKuizDV0Kk= eu. 86366 IN DNSKEY 256 3 7 AwEAAb7UvT6q/qhscgKJPNDxrnB0Y8mMUqWMD1E69J4vzBc6dqKMckyC H49Sq//3+5mVBshLV3EZORl5guWDIcwJtWeGIgpzRjqDIgkJrDy4mPq1 4qv4mR3gvpsEKCKdSTR8FH+rcKd3aB7SYQLaNF2gqaZloAqjMBnffVd2 xlc4bWVP
(btw, these are the same keys we got separately a moment ago to check the key tags). At this point, the process should be clear: dig requests the signatures for the above RRset (lines 54 and 55), which are self-signed, and thus it needs to get the DS record from the parent of eu., which finally is the root zone: lines 62 and 63 are the DS RRset for eu. in the root zone, and the signature is at line 67, created with key 40288, which is the root's ZSK (dig hasn't got it yet, but if you go back to the paragraph where we downloaded the root keys you'll see it).
After another round of verifications (lines 72-80), dig goes on to verify the signatures on the DS records, so it requests the DNSKEY RRset for the root zone (lines 86 and 87) and the associated signature (line 91). Note that this signature is created with key 19036 which is the root's KSK.
But key 19036 is also one of the keys we originally put in the root.keys file (along with key 40288, as said). After dig tries to fetch a DS record for the root which does not exist, it finally realizes that the keys it wants to verify are trusted because they are in the supplied trusted key file (lines 105 and 106). At this stage, dig has successfully verified the whole chain of trust from www.eurid.eu up to the root, and declares success (line 109).
As mentioned previously, since ultimately it is the KSK that is used to create the topmost signature, the verification would have been successful even if the trusted key file had contained only the KSK (tag 19036). It would have failed, instead, if the only trusted key had been the ZSK (40288).
Top-down verification
The validation we just performed is a so-called "bottom-up" validation, similar to what happens when SSL certificates are verified: every stage validates the previous one, going up until a trusted key is found, at which point the whole chain (not yet validated until then) suddenly is declared valid by the transitive property of trust. In the DNSSEC world, this means starting from the domain name to verify, and going up towards the root.
But given the way trust chains are built in DNSSEC, it should also be possible to perform a "top-down" validation, starting from the root and going down towards the domain name that needs to be verified. Indeed, dig permits to run a "top-down" validation, using the +topdown option.
$ dig +sigchase +topdown +trusted-key=./root.keys www.eurid.eu. A | cat -n 1 ns name: 198.41.0.4 2 ns name: 192.228.79.201 3 ns name: 192.33.4.12 4 ns name: 128.8.10.90 5 ns name: 192.203.230.10 6 ns name: 192.5.5.241 7 ns name: 192.112.36.4 8 ns name: 128.63.2.53 9 ns name: 192.36.148.17 10 ns name: 192.58.128.30 11 ns name: 193.0.14.129 12 ns name: 199.7.83.42 13 ns name: 202.12.27.33 14 15 Launch a query to find a RRset of type A for zone: www.eurid.eu. with nameservers: 16 . 518385 IN NS a.root-servers.net. 17 . 518385 IN NS b.root-servers.net. 18 . 518385 IN NS c.root-servers.net. 19 . 518385 IN NS d.root-servers.net. 20 . 518385 IN NS e.root-servers.net. 21 . 518385 IN NS f.root-servers.net. 22 . 518385 IN NS g.root-servers.net. 23 . 518385 IN NS h.root-servers.net. 24 . 518385 IN NS i.root-servers.net. 25 . 518385 IN NS j.root-servers.net. 26 . 518385 IN NS k.root-servers.net. 27 . 518385 IN NS l.root-servers.net. 28 . 518385 IN NS m.root-servers.net. 29 30 no response but there is a delegation in authority section:eu. 31 32 33 Launch a query to find a RRset of type DNSKEY for zone: . 34 35 ;; DNSKEYset: 36 . 86400 IN DNSKEY 256 3 8 AwEAAcAPhPM4CQHqg6hZ49y2P3IdKZuF44QNCc50vjATD7W+je4va6dj Y5JpnNP0pIohKNYiCFap/b4Y9jjJGSOkOfkfBR8neI7X5LisMEGUjwRc rG8J9UYP1S1unTNqRcWyDYFH2q3KnIO08zImh5DiFt8yfCdKoqZUN1du p5hy0UWz 37 . 86400 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0= 38 39 40 ;; RRSIG of the DNSKEYset: 41 . 86400 IN RRSIG DNSKEY 8 0 86400 20101124235959 20101110000000 19036 . SmZKqR1XNc73PUkVI6YRlXwcxeLfUmvLpikKaxTg+HmYCyWrmxzmYv/1 onFpCl8EZ75sGwIM78QCIekH+V1Azoc29fOx/NyWh86wc4bUqouoLXCH 99rEz2024pu8ZaC7ly1/HO+SCCV0ALT03/UvdwloEBl60bqBXZvN44K7 RIBqeLFOdXMHa5G8dNlopZaKsV5+0CGD28CgkC07A5//sumpEzGDmeq2 9gAGHk4WIpBL2EzUtToJRfdygpelA4akf+c32PkQGEEkjeDCEi1XCiwn lTCBiGrDAqYW5ivUb26h0twVH7vJlDWCR57/Q7SroV4oljK1tXkSL8bL 9beusw== 42 43 ;; Ok, find a Trusted Key in the DNSKEY RRset: 40288 44 ;; Ok, find a Trusted Key in the DNSKEY RRset: 19036 45 ;; VERIFYING DNSKEY RRset for . with DNSKEY:19036: success 46 47 ;; DSset: 48 eu. 86400 IN DS 61179 7 1 87E2B3544884B45F36A0DA72DADCB0239C4D73D4 49 eu. 86400 IN DS 61179 7 2 3B526BCC354AE085AD9984C9BE73D271411023EFF421EF184BCE41AC E3DE9F8B 50 51 52 ;; RRSIGset of DSset 53 eu. 86400 IN RRSIG DS 8 1 86400 20101123000000 20101115230000 40288 . H6evquVeN2Nb6MZacZn0Bt64ViDiOcFcu9hpTJs6f4Q3iLjs6X6f4/wi p2SJOeD3VJ78E7PD8wOdzbFfjm8/MnQd5wZNavaH+Jegj1pb9q1GzBfr qM9Oq6gjnCLK3TiYh9WKlz4q0OQPBUQBvO293/R0bQu6hCCA2DHF16qw bkM= 54 55 ;; VERIFYING DS RRset for eu. with DNSKEY:40288: success 56 ns name: 194.0.1.19 57 ns name: 195.47.235.130 58 ns name: 193.2.221.60 59 ns name: 217.29.76.13 60 ns name: 91.200.16.100 61 ns name: 194.146.106.90 62 ns name: 195.66.241.178 63 64 Launch a query to find a RRset of type A for zone: www.eurid.eu. with nameservers: 65 eu. 172800 IN NS x.nic.eu. 66 eu. 172800 IN NS p.nic.eu. 67 eu. 172800 IN NS l.eu.dns.be. 68 eu. 172800 IN NS m.nic.eu. 69 eu. 172800 IN NS a.nic.eu. 70 eu. 172800 IN NS y.nic.eu. 71 eu. 172800 IN NS l.nic.eu. 72 73 no response but there is a delegation in authority section:eurid.eu. 74 75 76 Launch a query to find a RRset of type DNSKEY for zone: eu. 77 78 ;; DNSKEYset: 79 eu. 86400 IN DNSKEY 257 3 7 AwEAAc8eyl1THSdL4ZHXK4i5q7OfkxnbY6pA3vzs1O4CeF8wkR5yIHmd xhXfP17uIj73Fpr4ZU+5mK4N3vmJKtWV0ML3ieO1bXvPpuNEEvXmkNOK EUSAfnk9CT8AlS5jiJz6hpzkYd6OFIrnQVgIqGWOqRdx+1sMXBO+IuKh gvYLunsSZyBTWftiHy11NeGMNPA4QO4fcS/IgJIjvpYtr0lhlmwiyS5k c6fz8CD1YmiSzIAIcrqBfOi6/VCarEFxZsEhRi+UFp3ipUz6s8zZ+T8x lDxgRyScApiudiZKor/omLn+JUo4hAaJFo0R2EbnZY7hiK71DkTA2yY+ 3VKuizDV0Kk= 80 eu. 86400 IN DNSKEY 256 3 7 AwEAAb7UvT6q/qhscgKJPNDxrnB0Y8mMUqWMD1E69J4vzBc6dqKMckyC H49Sq//3+5mVBshLV3EZORl5guWDIcwJtWeGIgpzRjqDIgkJrDy4mPq1 4qv4mR3gvpsEKCKdSTR8FH+rcKd3aB7SYQLaNF2gqaZloAqjMBnffVd2 xlc4bWVP 81 82 83 ;; RRSIG of the DNSKEYset: 84 eu. 86400 IN RRSIG DNSKEY 7 1 86400 20101119124925 20101112114925 37319 eu. vafh1utSPWOs4EZ9OS0KCeZxxTJEPge+LTjcdR9aQUcxdqVHceqr48RK mKuwi6U+qzZ0mXYz06V3Gn2apqayWOxNg/geIVf+5DsKNwkgaaHr1zHi sCxKcLikSevxTH2g3PwbAq1PBPillnNpmasKUwJ97MRyhTT0kj9wUx56 tUs= 85 eu. 86400 IN RRSIG DNSKEY 7 1 86400 20101119124925 20101112114925 61179 eu. UrsoJdsyKuxhClgR8IiRN5iq/IDrOp5ElZ9PKyA0wULZD3aQtHB4USSB t4fJzgN6KbaCBwBSSsG0eWi5U+krquvkzGxqlYJD+9+Gtm4HlZpxATQ5 2rIytsR+vtCmeu2YrC42lGa4iF0oQ2rfzQvonGezWtdPUDI6Z9VdLeFu muw3BQO87NIrWF00VaVVXZotdwRFH7EA29v7snbLL5BpSaiSBlGCALhk 2dEleVbg8YcKTg/cgr2fasHrN0lGc2Dv8l5Ph2U6GMIb2DBAC22RqYk8 HhrbTXDacgbMVtcYIBprQ9JN6jZSXxmzl5RDedeoUQJgRR7QQ4cOiRYZ MUJm4g== 86 87 ;; OK a DS valids a DNSKEY in the RRset 88 ;; Now verify that this DNSKEY validates the DNSKEY RRset 89 ;; VERIFYING DNSKEY RRset for eu. with DNSKEY:61179: success 90 91 ;; DSset: 92 eurid.eu. 86400 IN DS 34023 7 1 C0C4ABA58090643AE17BA8493C4AD2295D4D1376 93 94 95 ;; RRSIGset of DSset 96 eurid.eu. 86400 IN RRSIG DS 7 2 86400 20101122031929 20101115023628 37319 eu. rPrB+fdy1/oBoDosNKQhvVrTI3VeOkYVcNZgthsqt7DwlWNJ5NrRKfnF KbVzuiMpAHCBT+dWb9SRimBqCYGHHxSXym6gkWlAA0qJLV9HHqKZ7RF8 Ogro4mrknmxIKjgh/SNWZ4u9AN7rzeA9vuJHeYV6S3UefQMlSh9Par2Y WeE= 97 98 ;; VERIFYING DS RRset for eurid.eu. with DNSKEY:37319: success 99 ns name: 91.200.16.100 100 ns name: 195.66.241.178 101 ns name: 195.47.235.130 102 103 Launch a query to find a RRset of type A for zone: www.eurid.eu. with nameservers: 104 eurid.eu. 86400 IN NS a.nic.eu. 105 eurid.eu. 86400 IN NS l.nic.eu. 106 eurid.eu. 86400 IN NS p.nic.eu. 107 108 109 110 Launch a query to find a RRset of type DNSKEY for zone: eurid.eu. 111 112 ;; DNSKEYset: 113 eurid.eu. 86400 IN DNSKEY 257 3 7 AwEAAbu3N0HTlocsABTY4SmW5Et6kAwa1BHg2Jmjcy87VIvKrubLCjeO FLbC2hklqnlZvlyUI5DzmS3YW/1iGNQJ+u9Rdv63BWq1HPCimkxJasSQ vIff1zTYDujCucJgnn5Y3nVnJYaRvn3pmaQYmVA4jL/b3vuOmCI1jNxU NKnfxYXntYBEvfU2C824Bsv+ngKwAVIW/+3dtDhCsHfYzN8lIRHXR9yi G3/sLvFUDUH4n9qIwYGFQ00Kiv/j35VGWwruLS2nj98tw2zEgKg9otcu natVSltUnajuauaTamSTDU/cKk45QHumbQxqxQ6CMv3irDsfVYh85tUe MtiXTb4Sn7s= 114 eurid.eu. 86400 IN DNSKEY 256 3 7 AwEAAecbZhciFc12GqKd3NSd40FpZ4PyXwfvnQ7makOUaY+McBWnkK6h j/6TvR+/UafBjxPcL6Dmv9UG+FFdiJJtoukC7IapbPkquA8ItnQrJp0R xWAAkJq5MlftKUAJfZGUgSlRHc6UBCHGjrJnf2QHN/NIFz5BzSPrhLiP 1/2wbDEF 115 116 117 ;; RRSIG of the DNSKEYset: 118 eurid.eu. 86400 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 34023 eurid.eu. TNQhHOH+TdsOzWglBBOUL5gUM7oHZbeFBis9e3PbDXN+wsD2yrOwek2A XczHFrtWoQp6i3eDWOvLwF4DltAjCiVKU+oPAbTJLnVldhWKA4Q+loK2 hl9NE8Txf8lUdRnSlqnewxkbdh3Ml7zUfPgKYWpYxd6/oE6SvOGLvNB5 i6y2lIXqgNyIwd7xL7Y1d+Jvto3U308c/jcws3xWvGkKVoqDBTH3+aaL n+g7VzcnKKusSAPr/aG+LBjXcnL46kWsPnSafFU4Qnw0V+ls8CpL0do7 TbGLVNWu5NVTLCC92orTIYOPRigV/Yg2f+hIiQiwoMIJssJQBQ8drCB+ yc01lg== 119 eurid.eu. 86400 IN RRSIG DNSKEY 7 2 86400 20101123113942 20101116113254 62990 eurid.eu. CdldAM01iqI684Cwe2AF6ZDh4J8ODkbM9Cey+1jUMbAgnORW/WONAUMl 7DFOzchltbBo/5s7kqzoBMUEp8P41dkuLancH9/dHI7pUUNnzprdFFQV 9G+4gIwD3as4og17oX+b1gkf8VyYx8qBEDtIxT9DPHYZ1FwUTX2mBlNf zck= 120 121 ;; OK a DS valids a DNSKEY in the RRset 122 ;; Now verify that this DNSKEY validates the DNSKEY RRset 123 ;; VERIFYING DNSKEY RRset for eurid.eu. with DNSKEY:34023: success 124 ;; VERIFYING A RRset for www.eurid.eu. with DNSKEY:62990: success 125 126 ;; The Answer: 127 www.eurid.eu. 600 IN A 195.234.53.204 128 129 130 ;; FINISH : we have validate the DNSSEC chain of trust: SUCCESS 131 132 ;; cleanandgo
Again, success. But the route to that result was different this time. To better follow the events, it helps (more than in the bottom-up case) to capture the network traffic with tcpdump or wireshark while the top-down verification is being performed.
Some detail in the following explanation are not evident from the output of dig, and have been gathered by looking at the captured traffic.
Here, dig starts out by looking for the root zone name servers (lines 1-13). Then it picks one of the root servers previously obtained, and asks for tha A record of www.eurid.eu. (lines 15-28). This looks like the beginning of what normal DNS servers do when resolving a name that they don't know: query the root servers. (Spoiler: this is indeed what dig will do, this being a top-down validation; but in the process, dig will also look for the relevant DNSSEC records and perform validation as it goes down the chain of referrals.)
Obviously, the chosen root server knows nothing about the requested A record, but it returns a referral to the eu. name servers (line 30). A non-DNSSEC resolver would just follow the referral at this stage and query one of the referred-to servers.
But before doing that and leaving the root zone, dig makes a last request for the root zone DNSKEY records and associated signatures (lines 35-41). After that, dig sees (lines 43 and 44) that the keys it just received are trusted (because they are in the trusted key file specified on the command line), and thus declares the signature created with them valid (line 45).
The previously obtained referral also included, in the authority section, the DS records of the eu. zone, along wth its signature, which are shown in lines 48-49 and 53 respectively. Since the DS signature was generated with the ZSK (40288), and dig is trusting that key already (because it is in the trusted key file, and even if it wasn't, because it was signed with the KSK, which is trusted), dig declares the DS record valid (line 55). Note that the DS records hashes the eu. KSK, tag 61179.
Now dig is finally ready to follow the referral it was given, and thus it picks one of the servers it was referred to (lines 56-62) and repeats the original query (lines 64-71). Again, no direct answer but a referral to the eurid.eu. nameservers is returned (line 73). Similarly to what it did for the root, before following the referral dig requests the DNSKEY records and associated signatures for eu. (lines 78-85), and the authority section of the reply will contain, along with the actual nameservers for eurid.eu., the signed DS records for eurid.eu. (lines 91-96).
Now dig finds that the KSK key mentioned in the parent DS record (61179) is indeed part of the DNSKEY RRset for eu., and its hash matches that in the DS (line 87). This makes it trusted, because the parent vouched for its validity by means of the DS record it signed. Since this key is now trusted, dig can verify the signature for the eu. DNSKEY RRset that was created with key 61179 (lines 88-89). Now an important point is that the signature covers the whole DNSKEY RRset, and that RRset also includes the ZSK (37319). Since the RRset has been verified, key 37319 also becomes trusted.
From the last referral, dig also has the DS data for eurid.eu. (it was in the authority section of the reply), which is signed with the eu.'s ZSK (37319), which has just become trusted. So, dig can now successfully verify the signature on the DS record (line 98). The DS references key 34023 in the child (eurid.eu.).
At this point, dig leaves eu. and follows the referral to eurid.eu.. The process repeats one more time. However, this time the queried server is authoritative for eurid.eu., and has the answer.
Lines 99-101 show the available servers for eurid.eu., and dig queries one of them in lines 103-106. The server returns a proper answer (notice there's no mention of referrals, unlike the previous queries). However, to verify the answer, dig needs to have the zone keys, and it asks for them and their signature in lines 113-114 (DNSKEY) and lines 118-119 (signatures). As it did previously, first it checks that the key 34023 that was mentioned at the parent DS is contained in the DNSKEY RRset and hashes to the value found in the DS (line 121). With that, it can verify that the DNSKEY signature created with that key is valid (line 123), and this also makes the ZSK (62990) valid because it's in the same RRset covered by the verified signature. But the ZSK, 62990, is also the key that was used to sign the A record for www.eurid.eu., which dig can thus now validate (line 124). This is the last, definitive validation step; it is successful, and dig eventually declares success (line 130).
Conclusion
Hopefully this analysis shows that the DNSSEC verification process isn't too complicated; it's just a bit involved, due to the way the chain of trust is built in DNSSEC. Readers are invited to report any error or inaccuracy they may find.
The two verification methods differ in that in the bottom-up verification dig always queries the same server (the one it finds in resolv.conf), while in the top-down verification it uses that server only to get the initial list of root servers, but after that it autonomously queries the authoritative servers for each zone it traverses.
A good DNSSEC debugging tool, which seems to use the top-down approach, is at this page provided by VeriSign. Another debugger, which offers graphical diagrams of the chain of trust, is here. However, both tools seems to validate only A/AAAA records.
Why does it fail on google? I thought they must be DNSSEC enabled. Just wondering if it is some crazy ISP DNS spoofing or google don't have it yet. Because your example domain from above worked for me.
$ dig +sigchase +trusted-key=./root.keys google.com. A | cat -n
1 ;; RRset to chase:
2 google.com. 28 IN A 74.125.228.4
3 google.com. 28 IN A 74.125.228.5
4 google.com. 28 IN A 74.125.228.6
5 google.com. 28 IN A 74.125.228.7
6 google.com. 28 IN A 74.125.228.8
7 google.com. 28 IN A 74.125.228.9
8 google.com. 28 IN A 74.125.228.14
9 google.com. 28 IN A 74.125.228.0
10 google.com. 28 IN A 74.125.228.1
11 google.com. 28 IN A 74.125.228.2
12 google.com. 28 IN A 74.125.228.3
13
14
15
16 Launch a query to find a RRset of type RRSIG for zone: google.com.
17
18 ;; RRSIG is missing for continue validation: FAILED
Where did you read that google.com has DNSSEC? All I can find is that their public DNS resolvers do DNSSEC validation, which is not at all the same thing.
That's also all I could find, and that's why I am asking.
So it seems they haven't got it yet.