Subject: Re: [Dcrup] ed25519 in DNS

From: Jeremy Harris <[email-masked]>
Date: Sun, 18 Mar 2018 17:09:58 +0000

On 22/01/18 17:30, James Cloos wrote:
> [Replying to a random mail in the thread.]
> 
> The optimal way to encode an eddsa public key in dns is raw binary with
> either hex, base32 or base64 for the presentation format.
> 
> But for dkim, since it is stuck with TXT and already uses base64 for
> k=rsa's p=, then base64 of the raw public key is the answer.
> 
> In base64 an ed25519 key will take 44 octets.
> 
> A records like this:
> 
>   v=DKIM1;k=ed25519;p=fjkXkmq6aJiRS2tycuHzHdCYRcA2WWgEs0oh+HoXz2g=

Unsure if this is the right place to ask, but...

while a site has both rsa and ed25519 keys, must a
different selector be used?  Or do multiple TXT records
for one selector suffice, with the verifying MTA required
to search for a match between the TXT record k=
and the signature a= ?

-- 
Thanks,
  Jeremy

---

From: Scott Kitterman <[email-masked]>
Date: Sun, 18 Mar 2018 18:20:50 +0000

>to search for a match between the TXT record k=

RFC 6376 paragraph 3.6.2.2 says, "TXT RRs MUST be unique for a particular selector name; that is, if there are multiple records in an RRset, the results are undefined."

I think it has to be a different selector.

Scott K

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Tue, 20 Mar 2018 11:43:49 +0000

Typo in Section 4.2 ("mignt" should be "might").

Also, I'm ignorant about these things, so bear with me: The format chosen
for DNS in the draft is "the ed25519 public key encoded in base64".  Is
this the same as what we did for RSA keys, where it's just the PEM format
of the key with all the guard strings and wrapped lines removed, or is
there more to it than that?

-MSK

On Tue, Jan 23, 2018 at 3:50 AM, John R. Levine <[email-masked]> wrote:

> Will the author of the draft please pick on and update the draft soon.  If
>> anyone on the WG has good rationale for disagreeing with the author’s
>> choice, think twice and post it.
>>
>
> The people have spoken and seem to have said base64.  Updated draft
> posted, also with style edits per Dave's suggestions.
>
>
> Regards,
> John Levine, [email-masked], Primary Perpetrator of "The Internet for
> Dummies",
> Please consider the environment before reading this e-mail. https://jl.ly
>
> _______________________________________________
> Dcrup mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dcrup
>
>

---

From: Jeremy Harris <[email-masked]>
Date: Tue, 20 Mar 2018 11:58:30 +0000

> there more to it than that?

It's very different; there's _less_to it than that.
It's the raw key number; b64-encoded.  Unlike for RSA
keys, there is no ASN.1 wrapping.

It's quite difficult to generate the string, or at least
was as of a few months ago.  I ended up writing a little
program, using a GnuTLS version I found only on Fedora
Rawhide.  None of the utility programs commonly found
for GnuTLS, OpenSSL or NSS appeared to support the need.

Published ways of doing it would be a good thing.
-- 
Cheers,
  Jeremy

---

From: "John R. Levine" <[email-masked]>
Date: 20 Mar 2018 12:27:42 +0000

> there more to it than that?

There's much less.  The RSA key is a blob of ASN.1 that wraps subparts, 
while the ed25519 key is just the bare 32 byte public key in base64.

Should you have a PEM format ed25519 key it's up to you to pick the actual 
key out of the ASN.1.

Regards,
John Levine, [email-masked], Primary Perpetrator of "The Internet for Dummies",
Please consider the environment before reading this e-mail. https://jl.ly

---

From: "Salz, Rich" <[email-masked]>
Date: Tue, 20 Mar 2018 12:47:13 +0000

Don't do any crypto, just take the raw key data and base64 encode it, right?

On 3/20/18, 7:58 AM, "Jeremy Harris" <[email-masked]> wrote:

---

From: "John Levine" <[email-masked]>
Date: 20 Mar 2018 13:09:48 +0000

In article <[email-masked]> you write:
>>different selector be used? 

>I think it has to be a different selector.

Agreed.  Multiple key records at the same name would open a can of worms.  (If you can have two keys of
different k=, how about keys with different h= ?)

R's,
John

---

From: Scott Kitterman <[email-masked]>
Date: Tue, 20 Mar 2018 13:27:21 +0000

>Published ways of doing it would be a good thing.

I guess it depends on the tools.  For me it was completely trivial.  See GenEd25519Keys at line 50 in https://git.launchpad.net/dkimpy/tree/dknewkey.py for private key generation and ExtractEd25519PublicKey at line 82 for generating the private key and then extracting the public key from it.

Of course now that it's written, it's even easier to just run the script.

Scott K

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Tue, 20 Mar 2018 13:47:27 +0000

> Published ways of doing it would be a good thing.

That's what I was thinking.  Extracting something from a PEM-formatted RSA
key and putting it in the DNS requires a tiny amount of programming,
because I don't care what's under the base64.  As I understand it, the way
we're choosing to do this requires a PEM-formatted ed25519 to be
base64-decoded and then parsed somehow to extract only a key number, and
then re-base64 that and put it in the DNS.

-MSK

---

From: "John Levine" <[email-masked]>
Date: 20 Mar 2018 14:06:28 +0000

>Don't do any crypto, just take the raw key data and base64 encode it, right?

Right.

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Tue, 27 Mar 2018 20:28:51 +0000

On Tue, Mar 20, 2018 at 1:27 PM, Scott Kitterman <[email-masked]>
wrote:

> I guess it depends on the tools.  For me it was completely trivial.  See
> GenEd25519Keys at line 50 in https://git.launchpad.net/dkim
> py/tree/dknewkey.py for private key generation and
> ExtractEd25519PublicKey at line 82 for generating the private key and then
> extracting the public key from it.
>

A raw 32-byte integer is certainly small, but is it painful to leave it in
ASN.1 and store it that way?  It certainly fits in a DNS record, has a
fixed format, is more idiomatic (i.e., standard) when manipulating crypto
objects, and there's no ambiguity around how to interpret it.

The process to extract one with OpenSSL is to generate the private key,
then get the public key, then extract it in binary form, then chop the
leading dozen bytes, then base64 that, or:

$ openssl genpkey -algorithm ed25519 -outfile test.pem
$ openssl pkey -outform DER -pubout -in test.pem | tail -c +13 | openssl
base64

Meanwhile, DKIM users are already used to something more like:

$ openssl genpkey -algorithm ed25519 -outfile test.pem
$ openssl pkey -outform PEM -pubout -in test.pem

...and then taking that base64 blob and sticking it in the DNS as-is.
Since that's guaranteed to fit, why don't we stick with it?

Or, if we really think the integer-only approach is the right one, don't we
have to specify stuff like byte order?

-MSK, participating

---

From: Scott Kitterman <[email-masked]>
Date: Tue, 27 Mar 2018 23:16:11 +0000

On March 27, 2018 8:28:51 PM UTC, "Murray S. Kucherawy" <[email-masked]> wrote:
>....and then taking that base64 blob and sticking it in the DNS as-is.

It's sufficiently defined by  RFC 8032 and Base64.  I don't think there's a standardized ASN.1 structure for this.  I think ASN.1 is needless complexity.

Scott K

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Wed, 28 Mar 2018 03:14:35 +0000

On Tue, Mar 27, 2018 at 11:16 PM, Scott Kitterman <[email-masked]>
wrote:

> It's sufficiently defined by  RFC 8032 and Base64.  I don't think there's
> a standardized ASN.1 structure for this.  I think ASN.1 is needless
> complexity.
>

But DKIM applications are already used to that complexity, or they use APIs
to make it invisible to them.

The entire ASN.1 output from OpenSSL for an Ed25519 public key, expanded:

    0:d=0  hl=2 l=  46 cons: SEQUENCE
    2:d=1  hl=2 l=   1 prim: INTEGER           :00
    5:d=1  hl=2 l=   5 cons: SEQUENCE
    7:d=2  hl=2 l=   3 prim: OBJECT            :ED25519
   12:d=1  hl=2 l=  34 prim: OCTET STRING      [HEX
DUMP]:0420A5C55ABC4EEF3160EDDA69134DE4A1EF3FFCB769D7243BD5D774D33585B66924

That doesn't seem overly complex, certainly when compared to what an RSA
key looks like, and we've dealt with those for a decade.

-MSK

---

From: Scott Kitterman <[email-masked]>
Date: Wed, 28 Mar 2018 04:09:52 +0000

>key looks like, and we've dealt with those for a decade.

True and I could certainly deal with it, but why?  It's simpler than RSA, but more complex than RFC 8032 pubkey -> base64, which is what we have now.  Everything except the HEX DUMP OCTET STRING in the above is overhead we don't need.

Where is this ASN.1 structure standardized?  As far as I can tell, it's an openssl implementation detail.  Why do the harder, non-standard thing?

Let's not fetishize ASN.1 because we've been stuck with it for so long.  I don't think "we've long dealt with the extra complexity when we had to, so let's keep doing it when we don't" is a great argument.  

RSA keys have enough structure that, particularly for the private key, I can see ASN.1 making sense.  None of that applies to ed25519.

Scott K

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Wed, 28 Mar 2018 05:13:03 +0000

On Wed, Mar 28, 2018 at 4:09 AM, Scott Kitterman <[email-masked]>
wrote:

> True and I could certainly deal with it, but why?

As I said earlier, because it's the de facto standard way of representing
crypto objects in general, and it mirrors the way DKIM already does things.

> It's simpler than RSA, but more complex than RFC 8032 pubkey -> base64,
> which is what we have now.  Everything except the HEX DUMP OCTET STRING in
> the above is overhead we don't need.
>

It's 12 bytes you just ignore.

> Where is this ASN.1 structure standardized?  As far as I can tell, it's an
> openssl implementation detail.  Why do the harder, non-standard thing?
>

Looks like it's in draft-ietf-curdle-pkix, I think, which is on the
standards track, while RFC8032 is informational.

Let's not fetishize ASN.1 because we've been stuck with it for so long.  I
> don't think "we've long dealt with the extra complexity when we had to, so
> let's keep doing it when we don't" is a great argument.
>
> RSA keys have enough structure that, particularly for the private key, I
> can see ASN.1 making sense.  None of that applies to ed25519.
>

I have no particular love for ASN.1, but I'm swayed by the fact that
"public keys in DKIM are in ASN.1 encoded in PEM" is a lot easier to
explain to someone than "public keys in DKIM are in ASN.1 encoded in PEM
for key type A, or a little-endian 32-byte integer encoded in base64 for
key type B, or ... or ... or ...", and the cost of the former is, well, 12
bytes.

-MSK

---

From: denis bider <[email-masked]>
Date: Wed, 28 Mar 2018 01:00:01 -0500

I agree with Scott here 100%.

ASN.1 is crud. Even in situations where some kind of metadata is needed,
ASN.1 is a premature space optimization at cost of practicability
(complexity of ASN.1 handling) and security (ASN.1 parsing flaws). Even
where metadata is needed, if it's possible to get rid of ASN.1, it should
be gotten rid of.

Here no metadata is needed at all. 32-byte Ed25519 keys are well specified.
That's their preferred format. Adding ASN.1 would be total crud.

denis

On Tue, Mar 27, 2018 at 11:09 PM, Scott Kitterman <[email-masked]>
wrote:

> True and I could certainly deal with it, but why?  It's simpler than RSA,
> but more complex than RFC 8032 pubkey -> base64, which is what we have
> now.  Everything except the HEX DUMP OCTET STRING in the above is overhead
> we don't need.
>

---

From: Scott Kitterman <[email-masked]>
Date: Wed, 28 Mar 2018 06:05:33 +0000

>key type B, or ... or ... or ...", and the cost of the former is, well,

This isn't x.509, so I still think it's overkill, but at least it's written down somewhere.  Each new algorithm will come with it's own format, even if it's a different ASN.1 variant, so I still don't see the fact that RSA uses ASN.1 as relevant.  I still don't see value in the added complexity.

Let's see what others think.

Scott K

---

From: "A. Schulze" <[email-masked]>
Date: Wed, 28 Mar 2018 09:46:36 +0200

> Let's see what others think.

I'm not as technical involved but speak more as user.
As long as standard tools provide a convenient to handle keys I'm fine.

What are the usual tasks?
  - create a new DKIM key
    -> opendkim-genkey
    -> openssl genrsa -out $keyfile $keysize
    -> dknewkey --ktype ... $keyname

  - extract the public part
    -> opendkim-genzone
    -> use the file generated by dknewkey or opendkim-genkey
    -> some cut&pasted openssl-voodoo

The user don't (want to) care about ASN.1 is used or not.
 From this perspective it makes sense to avoid ASN.1 in new program code.

Andreas

---

From: Scott Kitterman <[email-masked]>
Date: Wed, 28 Mar 2018 15:25:30 -0400

Somewhat ironic in terms of timing, it's not like ASN.1 processing issues 
never happen (first issue):

https://www.openssl.org/news/secadv/20180327.txt

Scott K

On Wednesday, March 28, 2018 01:00:01 AM denis bider wrote:
> > On March 28, 2018 3:14:35 AM UTC, "Murray S. Kucherawy" <
> > 
> > [email-masked]> wrote:
> > >> It's sufficiently defined by  RFC 8032 and Base64.  I don't think
> > >
> > >there's
> > >
> > >The entire ASN.1 output from OpenSSL for an Ed25519 public key,
> > >
> > >expanded:
> > >DUMP]:0420A5C55ABC4EEF3160EDDA69134DE4A1EF3FFCB769D7243BD5D774D335
> > 
> > 85B66924
> >

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Thu, 29 Mar 2018 00:21:47 -0700

>    -> opendkim-genkey

opendkim-genkey does two things:

1) generate an RSA private key in PEM-formatted ASN.1; this is just an
execution of "openssl genrsa"
2) read that key and extract its matching RSA public key in PEM-formatted
ASN.1, and then just reformats it (without even decoding it) into a DNS TXT
record

>>    -> opendkim-genzone

This is used to turn an OpenDKIM-specific data set into a zone file.  It
doesn't do key generation.

> The user don't (want to) care about ASN.1 is used or not.

Users don't see ASN.1 in any case.  They see base64.

>From this perspective it makes sense to avoid ASN.1 in new program code.

But old program code doesn't use ASN.1 either, so I don't understand what's
changing at the user level.

I'm talking about the protocol level here.

-MSK

---

From: denis bider <[email-masked]>
Date: Thu, 29 Mar 2018 03:42:56 -0500

Hello Murray,

instead of arguing about the lack of harm in including crud that is not
necessary in this case, could you perhaps explain the COMPELLING NEED to
include crud that is not necessary in this case?

Your suggestion violates the principle of parsimonious design. This is that
nothing unnecessary should be included. Can you form an argument about why
this crud is NECESSARY, rather than expressing a preference for baroque
decorations?

denis

On Thu, Mar 29, 2018 at 2:21 AM, Murray S. Kucherawy <[email-masked]>
wrote:

> But old program code doesn't use ASN.1 either, so I don't understand
> what's changing at the user level.
>

---

From: "Rolf E. Sonneveld" <[email-masked]>
Date: Thu, 29 Mar 2018 12:43:41 +0200 (CEST)

Hi, 

> nothing unnecessary should be included.

If we were to design a new protocol this principle certainly applies. However, while the 'D' in DCRUP is about DKIM, we need to take the existing standards, practices and installed base into account as well. That means there are other principles that apply as well. 

> Can you form an argument about why this crud is NECESSARY, rather than
> expressing a preference for baroque decorations?

I don't think this is a fair characterization of Murrays contribution to the discussion. 

[...] 

> On Thu, Mar 29, 2018 at 2:21 AM, Murray S. Kucherawy < [email-masked] >
> wrote:

>> On Wed, Mar 28, 2018 at 12:46 AM, A. Schulze < [email-masked] > wrote:

>> 1) generate an RSA private key in PEM-formatted ASN.1; this is just an execution
>> of "openssl genrsa"
>> 2) read that key and extract its matching RSA public key in PEM-formatted ASN.1,
>> and then just reformats it (without even decoding it) into a DNS TXT record

>> This is used to turn an OpenDKIM-specific data set into a zone file. It doesn't
>> do key generation.

>>> >From this perspective it makes sense to avoid ASN.1 in new program code..

>> I'm talking about the protocol level here.

Can the DCRUP charter help us? 

<quote> 
Changes will be limited to existing 
implemented algorithms and key forms. Other changes to DKIM, such as new 
message canonicalization schemes, are out of scope. The WG will as far 
as possible avoid changes incompatible with deployed DKIM signers and 
verifiers. 
</quote> 

Especially the last sentence... 

/rolf

---

From: Scott Kitterman <[email-masked]>
Date: Thu, 29 Mar 2018 11:23:27 +0000

On March 29, 2018 10:43:41 AM UTC, "Rolf E. Sonneveld" <[email-masked]> wrote:
>If we were to design a new protocol this principle certainly applies.
>However, while the 'D' in DCRUP is about DKIM, we need to take the
>existing standards, practices and installed base into account as well.
>That means there are other principles that apply as well. 
>
>>> On Wed, Mar 28, 2018 at 12:46 AM, A. Schulze < [email-masked]
>> wrote:
>
>>>> - create a new DKIM key
>>>> -> opendkim-genkey
>

How does that relate to the formatting of public keys in DNS for a new algorithm?  It's inherently new and incompatible with deployed DKIM signers and verifiers.

Scott K

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Thu, 29 Mar 2018 13:18:23 -0700

> include crud that is not necessary in this case?

I thought I'd already done that, but I can re-summarize:

1) ASN.1 is, whether we like it or not, the standard way to marshal crypto
objects between applications.

2) ASN.1 is, for better or worse, the way this is already done in DKIM with
RSA keys.

3) Having to explain that, in the DKIM context, "key type A is encoded with
method 1, key type B is encoded with method 2, key type C is ..." seems at
odds with claims of simplicity being mandatory.

Your suggestion violates the principle of parsimonious design.

We are optimizing for different things.  You're reducing bytes on the wire;
I'm reducing specification complexity and the need for a code branch for
each key type.

> This is that nothing unnecessary should be included. Can you form an
> argument about why this crud is NECESSARY, rather than expressing a
> preference for baroque decorations?
>

As I believe I also already said, I have no particular affinity for ASN.1
apart from consistency with what the security community, and indeed DKIM,
already does.

-MSK

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 29 Mar 2018 16:29:18 -0400

> objects between applications.

​It is one of the standards. It is not the only one used. It is not the one
we used in the CFRG work. ​

> 2) ASN.1 is, for better or worse, the way this is already done in DKIM
> with RSA keys.
>

​The RSA key structure is originally defined in the PKCS#1 specification as
ASN.1. The CFRG key formats are specified in the RFCs and they are not
ASN.1​

> 3) Having to explain that, in the DKIM context, "key type A is encoded
> with method 1, key type B is encoded with method 2, key type C is ..."
> seems at odds with claims of simplicity being mandatory.
>

​RSA keys are encoded according to PKCS#1
Ed25519 keys are encoded according to RFC ​8032

> We are optimizing for different things.  You're reducing bytes on the
> wire; I'm reducing specification complexity and the need for a code branch
> for each key type.
>

​That is what you think you are doing but as an implementer, I can assure
you that you are not. You are committing a layer violation as I explain in
my last message.​

> apart from consistency with what the security community, and indeed
> ​​
> DKIM, already does.
>

​
​
DKIM merely specifies an opaque blob which happens to be encoded as ASN.1
internally. ​

   k= Key type (plain-text; OPTIONAL, default is "rsa").  Signers and
      Verifiers MUST support the "rsa" key type.  The "rsa" key type
      indicates that an ASN.1 DER-encoded [ITU-X660-1997
<https://tools.ietf.org/html/rfc6376#ref-ITU-X660-1997>] RSAPublicKey
      (see [RFC3447 <https://tools.ietf.org/html/rfc3447>], Sections
3.1 <https://tools.ietf.org/html/rfc6376#section-3.1> and A.1.1) is
being used in the "p="
      tag.  (Note: the "p=" tag further encodes the value using the
      base64 algorithm.)  Unrecognized key types MUST be ignored.

Note that the specification of ASN.1 encoding is implicit in the algorithm
tag. Other tags may specify different encodings.

The RSAPublicKey structure is:

   An RSA public key should be represented with the ASN.1 type
   RSAPublicKey:

      RSAPublicKey ::= SEQUENCE {
          modulus           INTEGER,  -- n
          publicExponent    INTEGER   -- e
      }

Just the parameters, nothing else.

We do not wrap RSA keys in a SubjectPublicKeyInfo wrapper so to do so for
any other type of key would be inconsistent.

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Thu, 29 Mar 2018 13:43:19 -0700

On Thu, Mar 29, 2018 at 1:29 PM, Phillip Hallam-Baker <[email-masked]

>       indicates that an ASN.1 DER-encoded [ITU-X660-1997 <https://tools.ietf.org/html/rfc6376#ref-ITU-X660-1997>] RSAPublicKey
>       (see [RFC3447 <https://tools.ietf.org/html/rfc3447>], Sections 3.1 <https://tools.ietf.org/html/rfc6376#section-3.1> and A.1.1) is being used in the "p="

As I recall, we picked this because that's the format exported by the
openssl CLI for public RSA keys, and we were fine with that.  What's
different with Ed25519 keys?

-MSK

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Thu, 29 Mar 2018 13:51:23 -0700

> you that you are not. You are committing a layer violation as I explain in

I'm also an implementer, and it sure seems like I am when the code needs a
different function to read each key type, plain and simple.  And I don't
think that's the fault of the crypto library I'm using, because one means
"load a DER key" and one means "load a raw key", which is forced by the
current proposal to encode them differently.

I think I'm being forced to cope with a layering deviation, rather than
imposing one.

-MSK

---

From: "Salz, Rich" <[email-masked]>
Date: Thu, 29 Mar 2018 20:54:29 +0000

As I said before, popular toolkits do the ASN1/DER wrapping.

Let’s try to keep personalities out of this, please.

---

From: Scott Kitterman <[email-masked]>
Date: Thu, 29 Mar 2018 21:31:37 +0000

>As I said before, popular toolkits do the ASN1/DER wrapping.
...

Some do and some don't.  I'm going to have to add custom application code to go beyond RFC 8032, since libsodium matches that.  I can do that, but I still haven't seen anything that looks to me like anything other than "because we've always done it this way".

I still am not seeing a solid rationale for adding complexity from x.509 to this application of RFC 8032.  We've already demonstrated interoperability between two dissimilar implementations just using what's in RFC 8032.  I believe that is a reasonably solid proof that x.509/ASN.1 isn't needed.

I don't find the toolset argument very interesting either.  There is support in different tools for doing it either way.  I, of course, like the way that makes it easier given my tools and others will tend to like the way that makes it easier given theirs.  The specifics of the tools are ephemera that, I don't think should drive protocol design.

If using ASN.1 makes the protocol simpler, it might be useful to have someone describe what text could be removed from the draft if we went that direction.  Any volunteers?

Scott K

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 29 Mar 2018 19:11:47 -0400

On Thu, Mar 29, 2018 at 4:43 PM, Murray S. Kucherawy <[email-masked]>
wrote:

> On Thu, Mar 29, 2018 at 1:29 PM, Phillip Hallam-Baker <
> [email-masked]> wrote:
>
>> ​
>> ​
>> DKIM merely specifies an opaque blob which happens to be encoded as
>> ASN.1 internally. ​
>>
>> Note that the specification of ASN.1 encoding is implicit in the
>> algorithm tag. Other tags may specify different encodings.
>>
>

​What is different is that the use of RSA is described in PKCS #1 and its
successors which used ASN.1 to describe the public key blob format.

The use of the CFRG curves is described​ in the RFCs mentioned earlier and
we decided to stop using ASN.1 when we shipped them. The public key blob
format does not use ASN.1. It is just a bignum with an implicit length and
the sign encoded in a spare bit:

​        /// <summary>
        /// Encode this point in the compressed buffer representation
        /// </summary>
        /// <returns>The point encoded in the compressed buffer
representation.</returns>
        public byte[] Encode() {

            Translate(out var X0, out var Y0);

            byte[] Buffer = new byte[32];
            var YBuf = Y0.ToByteArray();
            Array.Copy (YBuf, Buffer, YBuf.Length);
            if (!X0.IsEven) {        // Encode the sign bit
                Buffer[31] = (byte)(Buffer[31] | 0x80);
                }
            return Buffer;
            }​

See, no ASN.1 at all. That is the implementation I use for JOSE, PKIX,
S/MIME and for everything else.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 29 Mar 2018 19:29:41 -0400

> different with Ed25519 keys?

​When it comes to standards, OpenSSL is a trailing, not a leading indicator.

JOSE, PKIX, S/MIME, everything requires the ability to export the key in
the RFC 8032 format which involves no ASN.1. I would be astonished if
OpenSSL did not support that.

I try to use existing code implementations but I have my own
super-structure that provides a means of applying keys in PKIX, JOSE,
XMLDigSig etc. applications. This means that as a matter of course I have
properties that expose:

A The raw key blob
​B The raw key blob wrapped in SubjectKeyPublicInfo
C The UDF fingerprint of the SubjectKeyPublicInfo

To generate a DKIM RSA key blob, I use Base64 (A).

To be consistent, the Ed25519 key should also be  Base64 (A).

---

From: denis bider <[email-masked]>
Date: Fri, 30 Mar 2018 02:42:41 -0500

> ASN.1 is, whether we like it or not, the standard way
> to marshal crypto objects between applications.

Not so.

It is standard for a limited selection of protocols, such as in TLS and
X.509; but not others, such as SSH.

It is standard with some algorithms, such as RSA and ECDSA; but not others,
such as DH or Ed25519.

It is standard with some libraries, such as OpenSSL, but not others, such
as NaCl.

>  ASN.1 is, for better or worse, the way this is already
> done in DKIM with RSA keys.

Yes - *RSA* keys.

You cannot safely assume that a DKIM signer or verifier has access to a
general-purpose ASN.1 library.

It's possible that a DKIM verifier uses one crypto library for RSA, and
another for EdDSA. EdDSA typically does not come with ASN.1 support because
it's designed to not need it. The library that the verifier uses for RSA
may not expose ASN.1 primitives.

It's possible that in a decade after EdDSA is added, a DKIM signer will not
even want to, or have to, implement RSA keys. This means it would have no
use for ASN.1 unless we add it now for EdDSA.

This means you're:

- Forcing DKIM verifiers to use a library that exposes ASN.1 primitives, or
that wraps EdDSA with ASN.1.

- Cajoling crypto libraries that implement EdDSA into supporting ASN.1 as a
first-class encoding when it's not meant to be.

>  Having to explain that, in the DKIM context, "key type A is encoded with
method 1,
> key type B is encoded with method 2, key type C is ..." seems at odds
with claims
> of simplicity being mandatory.

It's not difficult to explain.

- An RSA key is encoded in the form generally intended for use with RSA.

- An EdDSA key is encoded in the form generally intended for use with EdDSA.

An RSA key is structured, so an encoding has been required since day 1 for
implementations to be interoperable. At the time this decision was made,
ASN.1 was the choice du jour, so that's the interoperable format for RSA.

An EdDSA key is opaque, and already specifies its own encoding. It's
intended to be the simplest possible. This is the interoperable format for
EdDSA.

It's not hard!

---

From: denis bider <[email-masked]>
Date: Fri, 30 Mar 2018 03:01:57 -0500

"Popular toolkits" is both too generic and too generous. Let us name the
toolkits in question.

The toolkit in question is OpenSSL, and this push is an example of the open
source community assuming it is the end-all and be-all of all things.

This kind of push is the result of an assumption that "everyone" uses
(insert project), and therefore everyone should dance the way (insert
project) makes it easy to dance. There's no consideration for what
fundamentally makes sense, or what's convenient for people on other systems.

On Windows, one might use Windows CNG for RSA, and an external library for
EdDSA. To wrap an EdDSA key in ASN.1 may mean writing hundreds of lines of
DER encoding and BER decoding code, which is hundreds of lines of
opportunity for bugs.

Imposing this on other implementations simply because OpenSSL users would
find this slightly more convenient is not cool. Not to mention it
fundamentally does not make sense if viewing the protocol in a way that's
implementation agnostic!

---

From: "Salz, Rich" <[email-masked]>
Date: Fri, 30 Mar 2018 12:05:28 +0000

*   The toolkit in question is OpenSSL, and this push is an example of the open source community assuming it is the end-all and be-all of all things.

I wasn’t trying to push anything, sorry if it came across that way.

We will have to have a consensus decision on this.  Let’s let the discussion run for a few more days.  If you have anything new to mention, please speak up.  Otherwise it seems to me that the choice will be
                ASN1/DER wrap the Ed25519 key
                Just the key without wrapping.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 30 Mar 2018 10:20:10 -0400

On Fri, Mar 30, 2018 at 8:05 AM, Salz, Rich <[email-masked]> wrote:
>
> We will have to have a consensus decision on this.  Let’s let the
> discussion run for a few more days.  If you have anything new to mention,
> please speak up.  Otherwise it seems to me that the choice will be
>

​We did discuss this at length when we ​wrote RFC8032.

To get to clarity, I suggest that we STOP talking about ASN1/DER wrap and
instead talk about what is being proposed, a SubjectPublicKeyInfo wrap.

RSA Public keys are encoded in a RSAPublic structure to create a binary
blob.
Ed25519 Keys are encoded as a BigNum + sign bit to create a binary blob.

DKIM does not wrap the RSAPublic structure in a SubjectPublicKeyInfo
wrapper so to do so for Ed25519 is inconsistent.

PKIX wraps RSAPublic and Ed25519 keys in a SubjectPublicKeyInfo wrapper

The point I am making here is that the PKIX ASN.1 has an intentional break
in the encoding. It is not correct to say that the RSA Public key is
encoded in ASN.1 in PKIX, it is actually encoded as a binary blob whose
encoding is specified by the embedded OID.

​This is distinct from the way we encode RSA public keys in JSON and XML
Dig Sig where we do express the parameters directly.

The structure of a  SubjectPublicKeyInfo  is essentially no different from
alg="RSA", key="ekfFwLDhPiM79vAazmy71v1FdOMLcVTZ...". It is the ASN.1
version of {id, base64(value)}.

And as far as OpenSSL goes, the question is not whether it can emit Ed25519
keys in a SubjectPublicKeyInfo wrapper, it is whether it can emit the RFC8032
encoding which it needs to in order to support JOSE etc.

Every implementation of RFC8032 must implement the raw encoding because it
is an essential part of the spec. Only those libraries that support PKIX
based protocols require  SubjectPublicKeyInfo

---

From: "Mark D. Baushke" <[email-masked]>
Date: Fri, 30 Mar 2018 08:54:36 -0700

I am not in favor of ASN.1 and I believe it is not needed here.

+1 Just the key without wrapping.

	-- Mark

---

From: "Murray S. Kucherawy" <[email-masked]>
Date: Fri, 30 Mar 2018 10:11:51 -0700

> general-purpose ASN.1 library.

I made no such assumption.  My own implementation has no idea about ASN.1;
it relies instead on libcrypto to take care of that.  All I need is the
object that I need to pass to the verification function, whatever that is.
The only encoding/decoding it does directly is base64 because it has to be
stored in a DNS TXT RR.

I would really prefer not to have to call different functions for key
types, or have to describe any of that in a specification document, if it's
possible to converge on one thing.  Simplicity is my goal.

> may not expose ASN.1 primitives.

Yes, that's possible, but those are implementation details.  I'm talking
here only of the specification.

> It's not hard!

At no time did I claim it's hard.  It just seems unnecessary to me.

Please don't be condescending.

-MSK

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 30 Mar 2018 13:30:28 -0400

> possible to converge on one thing.  Simplicity is my goal.

​Which is exactly what we want and exactly the reason that we do not want
to wrap our opaque binary blob for Ed25519 because we do not wrap our
opaque blob for RSA.​

---

From: Stan Kalisch <[email-masked]>
Date: Fri, 30 Mar 2018 13:38:40 -0400

On Mar 29, 2018, at 7:11 PM, Phillip Hallam-Baker <[email-masked]> wrote:> 
> On Thu, Mar 29, 2018 at 4:43 PM, Murray S. Kucherawy
> <[email-masked]> wrote:[...]
>> different with Ed25519 keys?> 
> What is different is that the use of RSA is described in PKCS #1
> and its successors which used ASN.1 to describe the public key
> blob format.> 
> The use of the CFRG curves is described in the RFCs mentioned earlier
> and we decided to stop using ASN.1 when we shipped them. The public
> key blob format does not use ASN.1. It is just a bignum with an
> implicit length and the sign encoded in a spare bit[...]

In the interest of clarifying matters a bit, does anyone dispute these
two paragraphs?

Stan

---

From: James Cloos <[email-masked]>
Date: Fri, 30 Mar 2018 16:00:15 -0400

> +1 Just the key without wrapping.

Just to show how easy a raw key is, here is a quick bit of code to
generate and print out a key pair in base64 using libsodium:

/************************************************************************************************************/
/* Generate an ed25519 key pair for dkim using libsodium */

#include <stdio.h>
#include <sodium.h>

#define SK64LEN sodium_base64_ENCODED_LEN(crypto_sign_SECRETKEYBYTES, sodium_base64_VARIANT_ORIGINAL)
#define PK64LEN sodium_base64_ENCODED_LEN(crypto_sign_PUBLICKEYBYTES, sodium_base64_VARIANT_ORIGINAL)

int main( int argc, char* argv[] ) {
  unsigned char sk[crypto_sign_SECRETKEYBYTES];
  unsigned char pk[crypto_sign_PUBLICKEYBYTES];
  unsigned char sk64[SK64LEN];
  unsigned char pk64[PK64LEN];

  if (sodium_init() == -1) {
    return 1;
  }
  
  crypto_sign_keypair( pk, sk );

  puts( "PRIVATE:" ); /* PK64LEN and PUBLICKEYBYTES in the next line to outputs only the private key */
  puts( sodium_bin2base64 (sk64, PK64LEN, sk, crypto_sign_PUBLICKEYBYTES, sodium_base64_VARIANT_ORIGINAL ) );
  puts( "PUBLIC:" );
  puts( sodium_bin2base64 (pk64, PK64LEN, pk, crypto_sign_PUBLICKEYBYTES, sodium_base64_VARIANT_ORIGINAL ) );
}
/************************************************************************************************************/

It is released to the public domain or via the CC0 license, as anyone prefers.

And if one wanted hex, using sodium_bin2hex() instead of sodium_bin2base64()
is enough.

ASN.1 has no value whatsoever for eddsa.

Eliminating additional attack vectors like asn.1 was part of DJB's
stated motivation and that continued into the eddsa rfc.

-JimC
-- 
James Cloos <[email-masked]>         OpenPGP: 0x997A9F17ED7DAEA6

---

From: Alessandro Vesely <[email-masked]>
Date: Sat, 31 Mar 2018 17:37:22 +0200

> ASN.1 has no value whatsoever for eddsa.

FWIW, on a stock Debian stable install, I get:

$ grep -i base64 /usr/include/sodium/*.h
$ grep -i bin2hex /usr/include/sodium/*.h
/usr/include/sodium/utils.h:char *sodium_bin2hex(char * const hex, const size_t hex_maxlen,

Ale
--

---

From: Alessandro Vesely <[email-masked]>
Date: Sat, 31 Mar 2018 17:59:50 +0200

On Thu 29/Mar/2018 23:31:37 +0200 Scott Kitterman wrote: 
> 
> If using ASN.1 makes the protocol simpler, it might be useful to have
> someone describe what text could be removed from the draft if we went that
> direction.  Any volunteers?
I'd try and imagine an eventual rfc6376bis.

First the "complicated" alternative that Murray dreads:

   k= Key type (plain-text; OPTIONAL, default is "rsa").  Signers MUST
      support the "rsa" key type and SHOULD support the "ed25519" key
      type.  Verifiers MUST support both "rsa" and "ed25519" key types.
      The "rsa" key type indicates that an ASN.1 DER-encoded
      [ITU-X660-1997] RSAPublicKey (see [RFC3447], Sections 3.1 and
      A.1.1) is being used in the "p=" tag.  The "ed25519" key type
      indicates there is the little-endian binary number (see
      [RFC8032], Sections 5.1.5 and 7.1) in the same place.  (Note:
      the "p=" tag further encodes the value using the base64
      algorithm.)  Unrecognized key types MUST be ignored.

      ABNF:

      key-k-tag        = %x76 [FWS] "=" [FWS] key-k-tag-type
      key-k-tag-type   = "rsa" / "ed25519" / x-key-k-tag-type
      x-key-k-tag-type = hyphenated-word   ; for future extension

No doubt it can be bettered, I just naively mixed text from the draft and
rfc6376.  And alas I'm not good at wording...  Ditto for the next, more concise
alternative (it nearly saves two lines of text):

   k= Key type (plain-text; OPTIONAL, default is "rsa").  Signers MUST
      support the "rsa" key type and SHOULD support the "ed25519" key
      type.  Verifiers MUST support both "rsa" and "ed25519" key types.
      The key type indicates which ASN.1 DER-encoded [ITU-X660-1997]
      key is being used in the "p=" tag.  (See [RFC3447], Sections 3.1
      and A.1.1 for RSAPublicKey encoding;  [draft-josefsson-tls-ed25519]
      for SubjectPublicKeyInfo.)  (Note: the "p=" tag further encodes the
      value using the base64 algorithm.)  Unrecognized key types MUST be
      ignored.

jm2c
Ale
--

---

From: Scott Kitterman <[email-masked]>
Date: Sat, 31 Mar 2018 16:02:30 +0000

>/usr/include/sodium/utils.h:char *sodium_bin2hex(char * const hex,

That's because it was added in libsodium 1.0.14 and Debian Stable was released with 1.0.12.  The Python wrapper I used, PyNaCl, uses Python's native base64 function, so for my purposes, it didn't matter (my dkimpy-milter, that supports ed25519, is available in the Debian backports repository and works fine with libsodium 1.0.12).  In any case, support for something in a Debian stable release is hardly a leading indicator of things.

If anyone needs a newer libsodium in Debian stable backports, feel free to contact me off list, so this doesn't veer even more off topic.

Scott K

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Sat, 31 Mar 2018 14:07:03 -0400

Agreed, it is like fifteen minutes to write and another 30 checking you
have the big-endian thing right and haven't introduced an extra flip on the
byte order somewhere.

This took me no time at all in c#.

---

From: Stan Kalisch <[email-masked]>
Date: Sat, 31 Mar 2018 14:46:43 -0400

> On Mar 31, 2018, at 12:02 PM, Scott Kitterman
> <[email-masked]> wrote:>
> In any case, support for something in a Debian stable release is
> hardly a leading indicator of things.
Agreed.  Debian's level of deliberate reserve in adding features to
stable (which, of course, is a feature) doesn't really serve this for
illustrative purposes.

Thanks,
Stan