Subject: Re: [Curdle] AlgorithmIdentifier parameters in draft-ietf-curdle-pkix-03

From: str4d <[email-masked]>
Date: Sat, 11 Mar 2017 06:18:38 +0000 (UTC)

On 02/19/2017 02:14 AM, str4d wrote:
> Hi all,
> 
> In draft-ietf-curdle-pkix-03 there is very clear language around the
> expected behaviour of parser implementations regarding
> AlgorithmIdentifier parameters:
> 

[snip]

> The problem is that the Sun AlgorithmId class always adds a NULL when
> encoding if there are no parameters, for compatibility with Solaris [4].
> So AFAICT it is presently impossible for me to write an implementation
> that simultaneously:
> 
> - follows draft-ietf-curdle-pkix-03 correctly
> - can retrieve EdDSA keys from a default Java keystore
> 
> Is anyone in the WG aware of a workaround for this, or have links to
> past WG discussion on this point? I would think that Oracle should at
> least be made aware of this issue, but even if they changes this in Java
> 10, that doesn't help my implementation run on earlier Java versions.
> The only alternatives I see at this point are:
> 
> - Remove the NULL restriction from draft-ietf-curdle-pkix-03
> - Require that my library not be used with incompatible keystores (but
> a) I have yet to find a way to enforce this via the JCA, other than just
> refusing to implement support for PKCS8EncodedKeySpec, which is not
> particularly usable, and b) I don't yet know of a keystore that *will*
> implement this properly)

I have found the correspondence in the Curdle WG ML that added the NULL
restriction; I have copied in the relevant members to hopefully jog this
conversation. If there is no further discussion, then I will have no
alternative but to be non-compliant with the eventual RFC, as I have
been unable to find a way for my library to work with the default Java
keystore :(

Peter Gutmann <[email-masked]> wrote:
> Daniel Kahn Gillmor <[email-masked]> writes:
> >   Implementaions MUST NOT accept any of these OIDs with the
> >   parameters field present, even if parameters has a value
> >   of NULL.
> >
> >If we can convince the early implementations to hard-fail on that,
> >we can discourage anyone from generating those values in newer
> >implementations.
>
> +1.  For once there's no argument for supporting existing broken
> implementations, we can get it right from the start

I apologise for providing one :/

Cheers(-ish),
Jack

---

From: Daniel Migault <[email-masked]>
Date: Tue, 14 Mar 2017 17:04:05 +0000

Hi, 

We need to sort this out. Anyone from Oracle can provide feedbacks ? 

Please let us know if there is any consensus on relaxing the MUST NOT accept parameters even NULL ?

Yours, 
Daniel

-----Original Message-----
From: Curdle [mailto:[email-masked]] On Behalf Of str4d
Sent: Saturday, March 11, 2017 1:19 AM
To: [email-masked]; Russ Housley <[email-masked]>; Daniel Kahn Gillmor <[email-masked]>; Peter Gutmann <[email-masked]>
Subject: Re: [Curdle] AlgorithmIdentifier parameters in draft-ietf-curdle-pkix-03

[snip]

> least be made aware of this issue, but even if they changes this in 
> Java 10, that doesn't help my implementation run on earlier Java versions.
> a) I have yet to find a way to enforce this via the JCA, other than 
> just refusing to implement support for PKCS8EncodedKeySpec, which is 
> not particularly usable, and b) I don't yet know of a keystore that 
> *will* implement this properly)

I have found the correspondence in the Curdle WG ML that added the NULL restriction; I have copied in the relevant members to hopefully jog this conversation. If there is no further discussion, then I will have no alternative but to be non-compliant with the eventual RFC, as I have been unable to find a way for my library to work with the default Java keystore :(

Peter Gutmann <[email-masked]> wrote:
> >If we can convince the early implementations to hard-fail on that, we 
> >can discourage anyone from generating those values in newer 
> >implementations.
>

Cheers(-ish),
Jack

---

From: David Benjamin <[email-masked]>
Date: Tue, 14 Mar 2017 17:41:33 +0000

No, we should not relax the MUST NOT. We've learned from the previous
algorithms here that multiple options for encodings are an unnecessary
source of complexity and interop headaches. There should only be one
encoding and parsers need to enforce this to avoid an ecosystem mess.

On Tue, Mar 14, 2017 at 1:11 PM Daniel Migault <[email-masked]>
wrote:

> To: [email-masked]; Russ Housley <[email-masked]>; Daniel Kahn
> Gillmor <[email-masked]>; Peter Gutmann <[email-masked]>
> alternative but to be non-compliant with the eventual RFC, as I have been
> unable to find a way for my library to work with the default Java keystore
> :(
>
> _______________________________________________
> Curdle mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/curdle
>

---

From: str4d <[email-masked]>
Date: Tue, 21 Mar 2017 23:31:51 +0000 (UTC)

> encoding and parsers need to enforce this to avoid an ecosystem mess.

As the author of one such parser, I completely agree. Were this a
fully-custom stack (like BouncyCastle when using their keystore, or a
commercial offering), where I controlled everything below my parser, it
wouldn't be a problem. But when the input to my parser is being
transparently rewritten to a non-compliant encoding by standard
libraries of the programming language itself, my hands are tied.

How would the following language (or something to this effect) work as a
compromise?

   In this document we defined six new OIDs for identifying the
   different curve/algorithm pairs.  The curves being Curve25519 and
   Curve448.  The algorithms being ECDH, EdDSA in pure mode and EdDSA in
   pre-hash mode.  For all of the OIDs, the parameters MUST be absent.
   Regardless of the defect in the original 1997 syntax, implementations
   MUST NOT write out a parameters value of NULL, and MUST NOT accept a
   parameters value of NULL, EXCEPT where doing so is unavoidable due to
   legacy PKCS8 interpretation within the implementation language's
   standard libraries (such as Java's Sun security provider before
   version XX).

I can comply with this, because my implementation will write the single
correct encoding to any destination (keystore or otherwise, modulo
whatever PKCS8 transformations that destination applies), but being a
standalone Java parser it can't know whether it is receiving input from
the default keystore or a compliant one. In a language where the default
PKCS8 parser can be made compliant, the MUST NOT would remain enforced.

Alternatively, the MUST NOT can be left as-is, and I will consider this
a case of "know the rules you're breaking". My concern then would be my
code being copied into other projects without this understanding (which
I would attempt to alleviate via comments), or other independent Java
implementations running up against this issue and just ignoring the MUST
NOT entirely, leading to incorrect encodings being written out
(avoidance of which AFAICT is the primary motivator for the MUST NOT).

Cheers,
Jack

---

From: Russ Housley <[email-masked]>
Date: Thu, 23 Mar 2017 12:49:41 -0400

>   standard libraries (such as Java's Sun security provider before

EXCEPT is not defined in RFC 2119.

How is your proposed language any different in reality than:

  This document specified object identifiers for using Curve25519 and
  Curve448 for key agreement and digital signature.  Since none of these
  algorithm identifiers need parameters, the parameters MUST be absent.
  As a result of the defect in the AlgorithmIdentifier syntax published
  in 1997, some implementations produce a parameters value of NULL, even
  when the parameters ought to be absent.  Conforming implementations
  MUST NOT produce a parameters value of NULL, but conforming
  implementations MAY accept a parameters value of NULL for
  interoperability.

Russ

---

From: David Benjamin <[email-masked]>
Date: Thu, 23 Mar 2017 17:16:27 +0000

>   implementations MAY accept a parameters value of NULL for

I think that encourages normal implementations too much towards laxness,
which will harm the ecosystem. I don't particularly care which encoding it
is (with or without NULL), but there must be only one encoding. We've had
enough trouble with id-rsaEncryption's ambiguity in BoringSSL that I do not
think we would be willing implement a new scheme with two encodings.

If MUST NOT on the parser is problematic, perhaps SHOULD NOT? That said, I
do not follow what is wrong with MUST NOT. It sounds like this Java issue
is purely a local thing, right? That is, you don't expect such malformed
structures to escape into the ecosystem, but you need to be able to parse
the structures back out? In that case, there's need to encourage any other
implementation to be lax here. It's purely so that your parser gets the
conforming checkbox? But the serializer is already violating the MUST NOT,
so violate it in the parser too and add an explanatory comment next to the
code.

Or am I misunderstanding the situation?

David

---

From: str4d <[email-masked]>
Date: Sun, 26 Mar 2017 11:03:38 +0000 (UTC)

>> EXCEPT is not defined in RFC 2119.

Yeah, my apologies - I was writing in pseudo-language, but am new enough
to this sphere that this RFC isn't yet burned into my brain ^_^;

> which will harm the ecosystem.

Correct. I was trying to come up with something that maintained the
existing strictness as much as possible, because in theory I agree with it.

> I don't particularly care which encoding it

I'm *already* having to deal with parsing two encodings, due to the
presence of draft-josefsson-pkix-eddsa-04 (which was the active draft
for a proposed encoding when that part of my parser was contributed) -
so the horse has kinda left the barn already in that respect.

> Or am I misunderstanding the situation?

It's not so much that I want a "conforming checkbox" to tick, but that
I'm mindful of how easily context can be lost. You don't want to
encourage laxness by allowing flexibility, but you also don't want
implementors reading the RFC, discovering they can't implement it
correctly, and simply ignoring it - that will result in undefined
behaviour. I would prefer that the RFC explicitly acknowledge that the
MUST NOT may not be practical for *parsing* (as opposed to writing) in
some legacy instances (hopefully only the Java standard libraries), to
provide context to future readers instead of hoping they stumble upon
this mailing list thread, or upon the explanatory comment in my code.

I'll admit I'm a little surprised at my cynicism, but I don't think it
is misplaced. However, I am clearly the only person to have raised this
issue here, so perhaps I'm wrong, and RFC readers will interpret the
MUST NOT in a sensible way. I'd like to hope so.

Jack