[dns-operations] .nz DNSKEY encoding
Sebastian Castro
sebastian at nzrs.net.nz
Thu Jan 19 04:12:52 UTC 2012
Dear fellow DNS operators:
Back in December, we sent a notice to the NZNOG (New Zealand Network
Operators Group) mailing list explaining the particularities of the
encoded representation of .nz DNSKEY, where the first 6 characters are
"BAABAA" instead of "AwEAAb"
We sent the following explanation
------------------------------------------------------------------------
To provide a clear explanation, let's walk through the decoding of the
root zone DNSKEY:
. 107464 IN DNSKEY 257 3 8 (
AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ
bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh
/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWA
JQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXp
oY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3
LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGO
Yl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGc
LmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
) ; key id = 19036
. 107464 IN DNSKEY 256 3 8 (
AwEAAdNW7YIhcTdqXrzgZjJJ35VjAFT1ArvnhAzXDm7A
uGxSQqmGBRmjJvBv0xS4gahB9mj6ekF0dVKoeZgLmNAj
o8hj2JI7K281YTo2R5k3mKSc4hOCP55hR22r5hIsPJoT
19pv/VdZQfyTzZ96frQ16qRa9+/GSjzjtFfQv16FwE7R
) ; key id = 55231
The DNSKEY rdata is represented in BASE64, which once decoded, will
provide the public component of the key used to generate signatures.
According to RFC3110, the encoding for the key follows the structure below:
------------------------------------------------------------------------------
RSA Public KEY Resource Records
RSA public keys are stored in the DNS as KEY RRs using algorithm
number 5 [RFC2535]. The structure of the algorithm specific portion
of the RDATA part of such RRs is as shown below.
Field Size
----- ----
exponent length 1 or 3 octets (see text)
exponent as specified by length field
modulus remaining space
-------------------------------------------------------------------------------
For the root zone DNSKEY with the SEP bit on, the decoding looks like
dig dnskey . +short | grep '^257' | awk '{print $4}' | base64 -d | xxd
-l 12 -b
0000000: 00000011 00000001 00000000 00000001 10101000 00000000 ......
0000006: 00100000 10101001 01010101 01100110 10111010 01000010 .Uf.B
where
* exponent_length is the first byte (00000011). This indicates the next
three bytes are the exponent.
* exponent (00000001 00000000 00000001), which in decimal is 65537, the
4th number of Fermat.
* modulus is represented by the rest of the data.
The DNSKEY for .nz looks like
nz. 3600 IN DNSKEY 257 3 8 (
BAABAAGwfTiEoh71o6S55+Mdy1qqVRnpKY1VHznrv+wx
rPfvRGB5VivFFPFN+33fsaTxJQTceOtOna7IKxTffj6p
bBG4a9vtk2FqF551IwXomKWJnzRVKqYzuAx+Os/5gLIN
BH7+qRWAkJwCdQXIaJGyGmshkO5Ci5Ex5Cm3EZCeVrie
0fLI03Ufjuhi6IJ7gLzjEWw84faLIxWHEj8w0UVcXfaI
2VL0oUC/R+9RaO7BJKv93ZqoZhTOSg9nH51qfubbK6FM
svOWEyVcUNE6NESYEbuCiUByKfxanvzzYUUCzmm+JwV7
7Ebj3XZSBnWnA2ylLXQ4+HD84rnqb1SgGXu9HZYn
) ; key id = 2517
nz. 3600 IN DNSKEY 256 3 8 (
BAABAAGD+q3p2XDCb6SvAbACB/NPdljxhpBx2O9ZnvF2
OYb6kViMJ5dgxYDcFtvL5RW31Bc7UDvseoQPUK1wora3
BtUTylo1xd5PN/lV600mrNGRxfmw77Hen/MXH5GQrjaj
O+rFP1xce1/jdyvCciJzrYRcPL9p4c/eGoJK3ZMubiu1
OQ==
) ; key id = 27212
which once decoded, looks like
dig dnskey nz +short | grep '^257' | awk '{print $4}' | base64 -d | xxd
-l 12 -b
0000000: 00000100 00000000 00000001 00000000 00000001 10110000 ......
0000006: 01111101 00111000 10000100 10100010 00011110 11110101 }8....
In this case,
* exponent_length is the first byte (00000100), representing a decimal
value of 4
* exponent covers the next four bytes (00000000 00000001 00000000
00000001), which converted to decimal is 65537.
* modulus is represented by the rest of the bytes.
The encoding for the .nz DNSKEY is different. According to RFC3110,
Section 2
--------------------------------------------------------------------
Leading zero octets are prohibited in the exponent and modulus.
--------------------------------------------------------------------
So the encoding being used is RFC non-compliant. We tracked down the
issue to the PKCS#11 library recommended by the HSM manufacturer.
Despite the wrong encoding, everything is working as far as we are
aware, including validation using BIND 9.7 and Unbound 1.4.9,
reinforcing the spirit of Postel's Law.
Duane Wessels from Verisign reported our DNSKEYs cause some BIND
utilities to generate different results:
$ dig nz dnskey | grep 257 > nz.key
$ dnssec-dsfromkey nz.key
nz. IN DS 54026 8 1 CC0EFEDAA4AA09CFB05E72E765A97BD5A9BFD1FE
nz. IN DS 54026 8 2
48B0A194EE26C9D59BCC683CBC7A3495BB0AAA51ECC75533DBC76408 F0F70458
where the DS records submitted to the root zone are
nz. 6446 IN DS 2517 8 2 (
02240B41DFDDAECA2D6227D75A3575D5BA2FD07E2157
7F1C506D98BE491D6FF3 )
nz. 6446 IN DS 2517 8 1 (
CB5F686CB7A500B344E33DBC5CA8183A4E5579EC )
Other tools such as Net::DNS or ldns-key2ds produce the expected output.
----------------------------------------------------------------------------
The issue has been reported to the OpenDNSSEC developers including a
patch, so it should be in process of being included in the official release.
Despite our testing, we got a notification from Nominum indicating that
DNSSEC validation fails for .nz due to the DNSKEY encoding. It seems
they decode the DNSKEY and then re-encode it, and the results are not
the same aborting the validation.
We are sharing this information in case it helps other DNSSEC adopters.
We are currently in the process of deciding the best approach to change
the DNSKEY encoding, which from an external point of view looks like a
key rollover, but using the same cryptographic key :)
Kind Regards,
--
Sebastian Castro
DNS Specialist
.nz Registry Services (New Zealand Domain Name Registry Limited)
desk: +64 4 495 2337
mobile: +64 21 400535
More information about the dns-operations
mailing list