Subject: [DNSOP] Specification of DNSKEY "Private-key-format"

From: Mukund Sivaraman <[email-masked]>
Date: Thu, 29 Aug 2019 18:25:02 +0530

A tool such as BIND's dnssec-keygen generates the following formatted
private keys:

[muks@naina ~]$ cat Kexample.org.+008+10638.private
Private-key-format: v1.3
Algorithm: 8 (RSASHA256)
Modulus: 3GqHtpNGJk9obM8cIeQa5RqYJNd7ZMJ3tdOIauC8Rz7G3dhxQtTDWwW6vAg3xptDCR/s3l3FaSFTkXyoqqY2/zLTNWUqY2R043xs5ZXSZAwS7ZIUinjLU7m6glz9S1dM6r0h6qTl4NJ+u8Smib26cFEmSZBS/BUBYwc11XEtrwCDvZbZxgAehXXteE+zoUs/vp7HWFNJZkww9c4S1DBIwX/t3bV0fiCdv5gpptUmsjnd/2j9xhdrLm9SGMUYewlaF9hSjQ64PpFo34jErCarBXcr8aH9jYclydmMYlL7m6mFPWTWgZFBDkGdxhQnn9YMgq0ItHzABR12Usflj1PUVw==
PublicExponent: AQAB
PrivateExponent: rTknuSvbGKaVidXm5Rewr1cMNQAIILLYg9RfxKckMNW8UoMU2BIACdvh2n6W3wYMU/J8JHILgEjJtXAD2kFQvZUC+lasTnqXhmS17GSneSsoAP8qF31BRmaTlnpgMkLE10KWkiLP6rVjFkxBGcU67aRI881x+lzDv0DeZQVSgtHt+ZaogkJ7BH2etfKuDOxPuzvvNoh8Zaglm7zgzSh6fuFZxsIMSu7+FgTiqLTqs3O5wM6p494GbI5O3TbMZqCF+1B+uWfAblXwqbfQBQ6oZdG5WaHVSck27b5PVzd64JI/4bbLxpZoywE4xgkn8jyKl08XVGUmFHzGhE6dMJVIcQ==
Prime1: +FczIRoxjyJjRmoESH4Z7oZxvvkZHUE7wah/vUYvTs/LPZN/R0EZDA/HvLPN6vUtnkswnnkJKMN7YDSaciApbwvdlkPERBGgLn/SDBQTWzSAj7X0qu6v5EwOcZyVRUlnd2pBTuooKPB/A63RuIV5RNDbTcq6Hj9gejULF4kc6sk=
Prime2: 4zbZfUU30lknXPlsB3zyOEkFsJj2/O4p3KqDaQsd+vTSsQ4GqhwQhASk21LowgMCSskKAo0FJG2z7yFPHpdy/7q54G0vRD7iMU37ZK8+eO8WmAqS2c/hlfGJpioYGm9HjdFGyD6QWTTY+Yo3TOecv/Yfu3ZhVYsX4iFrgGplNh8=
Exponent1: QfAdQkfLKt8Nju+tTXY1+nA2GWfYdD0S2buclyvgecOQijv0in3NYbd66C6xmRYaU7JRKXKnrOwigQvWikDh33s+DZzWquAnMNF9evmFnizVidLdMNmJWEuddisGM0xnLXzH9GUV3rDkeJyZV64Q4eW2pPQT8N4RBsG4vToJtIk=
Exponent2: oWTcqDb6p9fcNhaVvdvq0kBMYlzFVHR4F96m6X6UFSbCYjHsWfkFYkFKOOBzpRwuDKExEw7IkE+8eCfY44oAjdY9IkVsRbXFRfB2mdZBMfXivq0EEuOvAatIc1eDN4PD9+CnvqVyM2tulBKxpVb/6PsTHz2/ddwPYvkKO3VX31E=
Coefficient: XbZCrBF9whoQEFDNlPnYCRYEM5Wq2TN0essxYsnv0fObssnzv3jJh5NGSzy+2+/gWPvYYe9vtPHhdYhdeRQ//iK1CnP3KlfsMluNXoslC00l+NHnQuu6qHCL5BxfIB8voiq2/NkjRAZufh1g4md1I/BMhA8pdoQs2bElxv6Mewc=
Created: 20190829125147
Publish: 20190829125147
Activate: 20190829125147
[muks@naina ~]$

I have looked around for a specification for this format, but I fail to
find one. Where is this specified? Has it ever been described in some
document?

		Mukund

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 29 Aug 2019 09:48:31 -0400

On Thu, Aug 29, 2019 at 06:25:02PM +0530, Mukund Sivaraman wrote:
> Modulus: [...]
> PublicExponent: [...]
> PrivateExponent: [...]
> Prime1: [...]
> Prime2: [...]
> Exponent1: [...]
> Exponent2: [...]
> Coefficient: [...]

Compare the above with:

    $ openssl genrsa 512 2>/dev/null | openssl rsa -text -noout | egrep -v ':..:'
    RSA Private-Key: (512 bit, 2 primes)
    modulus:
    publicExponent: 65537 (0x10001)
    privateExponent:
    prime1:
    prime2:
    exponent1:
    exponent2:
    coefficient:

And it becomes clear that what you're seeing is a sequence of tagged
base64 encodings of the BIGNUM elements of the CRT form of an RSA
private key.

> Created: [...]

Plus some additional metadata.

> find one. Where is this specified? Has it ever been described in some

This looks like an ad-hoc format, specific to dnssec-keygen and
friends.  In particular "Publish:" and "Activate:" are not part of
the key per-se and are rather related to the DNSSEC key lifecycle.

-- 
	Viktor.

---

From: Mukund Sivaraman <[email-masked]>
Date: Thu, 29 Aug 2019 19:25:54 +0530

Hi Viktor

> base64 encodings of the BIGNUM elements of the CRT form of an RSA

I am initimately familiar with what these fields mean and the code that
generates it. The question is not about what the meaning of these fields
are.

I am asking about where this key format is specified - I want to extend
it.

> _______________________________________________
> DNSOP mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dnsop
> 

		Mukund

--

Loop DNS nameserver: https://akira.org/loop/

---

From: Evan Hunt <[email-masked]>
Date: Thu, 29 Aug 2019 16:11:23 +0000

> I am asking about where this key format is specified - I want to extend

There's never been a written specification as far as I know, and if there
was one, then it's definitely been obsolete since 2009, because I changed
the format then and I didn't update any specs.

What I can tell you is: the private key file contains a format version
string, "Private-key-format", currently always set to 1.3, and an
algorithm string, "Algorithm".  After that comes a set of private keydata
fields which are specific to the algorithm, and finally a set of *optional*
metadata fields.

Those were introduced in format version 1.3. They include "Created",
"Publish", "Delete", etc, and also a few (such as "RollPeriod") that
were reserved for future use but we'e never gotten around to using them.

If the parser encounters any field that it doesn't recognize, and the key
claims to be version 1.3, then it will reject the key with an error.
However, if Private-key-format is increased to at least 1.4, then the
version 1.3 parser will ignore the unknown fields and just use the ones
that it does understand.  A version number above 2.0 is assumed not to be
backward-compatible, so that key would be rejected always.

We've have had a few conversations at ISC recently about adding some new
fields and increasing the format version to 1.4, so it would probably be
best if we coordinate our changes to ensure that your extensions are
interoperable with ours.

-- 
Evan Hunt -- [email-masked]
Internet Systems Consortium, Inc.

---

From: Mukund Sivaraman <[email-masked]>
Date: Fri, 30 Aug 2019 09:56:21 +0530

Hi Evan

> backward-compatible, so that key would be rejected always.

So it is a BIND-specific format. Years ago at ISC, I had looked for a
spec for it as I'd seen it used in some RFCs (e.g., RFC 6605) but could
not find one.

> best if we coordinate our changes to ensure that your extensions are

For interoperability, there are other BIND-specific formats to consider
too such as the journal file format, the control channel protocol,
etc. The journal format is already incompatible between Loop and BIND,
and the control channel will soon be. I also would like for these to be
compatible and am open to collaboration.

On the topic of the private key format, there are multiple Loop tickets
that would propose changes.

* Currently, an experimental feature is being developed that needs
  additional meta fields. This caused me to ask the question.

* As you know, historically the BIND tree on unix relied on /dev/urandom
  and /dev/random (or some custom device) as sources of random
  numbers. This was slow to use, and in some environments, ran out of
  entropy. Some parts such as the dispatch code added a CSPRNG for
  source port randomization to improve performance and availablility of
  randomness. The general design led to flaws in the implementation of
  some features. Recent BIND branches appear to have tried to address
  this by switching to a mix of OpenSSL's PRNG and a local
  implementation of xoshiro128**.

  Loop is increasingly using a different crypto library, which
  implements LibreSSL portable's arc4random() based on OpenBSD's
  arc4random() and uses ChaCha with thread-local random state. It has
  replaced all usage of randomness within Loop and various hacks that
  were in place to work around randomness availability and performance
  issues have been removed. For the first time, all usage of randomness
  within the Loop tree demonstrably passes NIST SP 800-22.

  There is a ticket to implement the features of what dnssec-keymgr
  provides within named itself for ease of use of key maintenance (it is
  still named named, and will be renamed to loopd soon). This will need
  changes to metadata in the private key format, but see the next item.

* Loop has been improving how it handles key material (in memory) but
  there is still some way to go. Two aspects that I dislike about how it
  stores private keys on filesystem is that (1) they are stored in the
  clear, and (2) metadata unrelated to key material is stored alongside
  key material, though these should be in human readable form even if
  the key material is stored encrypted. This is unlike the DER->PEM form
  that OpenSSL tools generate by default (e.g., in Viktor's example).
  The key material and schedule metadata should be separated into
  different files.

Again, I'd very much like to collaborate with ISC, but the ball is in
your court.

		Mukund

--

---

From: Evan Hunt <[email-masked]>
Date: Fri, 30 Aug 2019 05:19:50 +0000

On Fri, Aug 30, 2019 at 09:56:21AM +0530, Mukund Sivaraman wrote:
> etc.

Those seem like separate conversations to me, but I'm happy to have them.

I should clarify, while interoperability between Loop's and BIND's private
key files may well be useful, IMHO the main concern would be to prevent
accidents. If Loop uses what appear to be BIND-style K*.private files, but
you bump the format to 1.4, and BIND does the same with incompatible set of
changes, then BIND key files could break Loop, or vice versa.

So either we should ensure that two sets of changes are compatible with
each other (for example, each could recognize-but-ignore any new metadata
fields that are introduced by the other), or, failing that, we should ensure
that the two formats are *so* incompatible that nobody can cross the
streams by mistake.  You could change the K in the filename to some other
letter, for instance, and then BIND couldn't possibly try to load Loop's
keys.

But I'd be happy to discuss your proposed changes in hopes of maintaining
interoperability. We should probably take it off the list, however; I don't
think implementation details on this level are probably of much interest to
dnsop.

>   numbers.

FYI, no longer the case as of 9.14.

>   provides within named itself for ease of use of key maintenance

This is on our road map as well. AFAIK it doesn't require changes to
private keys, though.

>   The key material and schedule metadata should be separated into

Yep, that's a design decision I regret. And not just for the reason you
mention, but also because there was no good reason for the metadata to be
secret, and keeping it in a file that isn't publicly readable causes a lot
of inconvenience.  I wish I'd added a third file instead, such as
K*.meta, instead of extending K*.private.

However, IMHO, redesigning it now would inconvenience people rather more
than putting up with it does, so for the time being I don't expect it to
change.