Subject: Re: [Curdle] FW: New Version Notification for draft-ietf-curdle-pkix-04.txt

From: David Benjamin <[email-masked]>
Date: Mon, 01 May 2017 16:14:58 +0000

On Sun, Apr 30, 2017 at 8:17 PM Brian Smith <[email-masked]> wrote:

> Jim Schaad <[email-masked]> wrote:
> > It is not always possible to detect corruption when you store in an
> unencrypted form.
>
> What kind of corruption would we not be able to detect? It is possible
> that somehow the private key could get corrupted and that there could
> be a corresponding corruption to the public key such that they match
> again, but this seems extremely unlikely unless somebody simply
> replaced the key pair with another key pair.
>
> > It would also not be possible to know if it was the private key or the
> public key that has been corrupted, just that the two values do not match.
>
> This is the case with any kind of cryptographic check, including HMAC
> or whatnot.
>

(Not that it matters, but, to that end, would detecting corruption not be
just as easily served by stashing a checksum somewhere? If not external to
the serialization, there is already that attributes field.)

> > > However, unless this is documented in the draft one way or
> > another as a MUST accept or a MUST NOT generate, I think
> > it will be an interop nightmare. In particular, we should avoid
> > the situation where some implementations produce v2 keys
> > so they can add the publicKey field, and where other
> > implementations reject v2 keys because they only parse v1,
> > where the publicKey field isn't allowed.
> >
> > I have not heard that this is an issue today with DH keys.  This
> > makes me think that this is not going to be a big issue.  I expect
> > that most implementations would all for parsing v2 keys even if
> > they then ignore the public key field.
>
> If that's the expectation then let's enshrine that in the spec by
> saying that implementations MUST accept v2 keys for these types of
> keys.
>
> In particular, I have seen PKCS#8 implementations that reject any v2
> PKCS#8 file instead of ignoring the extra fields.
>

As the author of one such PKCS#8 implementation, I'd simply missed that v2
PKCS#8 existed. Happy to add support (by way of ignoring the field
probably, yeah). Lacking any useful text about what to do, I interpreted
the version field to be analogous to RSAPrivateKey, another PKCS spec.
There, an RFC 2437 implementation that attempted to be forwards-compatible
(by accepting unknown versions and ignoring appended fields) would have
been confused come RFC 3447, which decided v1 meant a
semantically-incompatible otherPrimeInfos field.

RFC 5958 continues this. It does use ASN.1 extension markers, but X.680
merely says "The action that is taken in each situation is determined by
the ASN.1 specifier", and RFC 5958 does not appear to say anything.

Is the intent that OneAsymmetricKey parsers accept a hypothetical v3 with
further appended fields, or should they reject those to allow for
RFC-3447-like changes? If so, how do they handle the version <=> extra
field correspondence? A numerical comparison? Assume all unknown values are
newer? The version number used in the ASN.1 tags corresponds to the
symbolic name of the version constants, rather than the numerical value, so
it's not obvious whether, say, defining v3(-1) would be acceptable.

David

---

From: Brian Smith <[email-masked]>
Date: Mon, 1 May 2017 08:51:36 -1000

> the serialization, there is already that attributes field.)

Yep, there would be many ways of doing it, but none standardized.

> RFC-3447-like changes? If so, how do they handle the version <=> extra field
> correspondence? A numerical comparison? Assume all unknown values are newer?
> The version number used in the ASN.1 tags corresponds to the symbolic name
> of the version constants, rather than the numerical value, so it's not
> obvious whether, say, defining v3(-1) would be acceptable.

There are multiple problems with rfc5958 and its use of version field
is one. Here is what I'm planning to do:

For now, for RSAPrivateKey and ECPrivateKey, accept only PKCS#8 v1,
since publicKey isn't necessary for them. Later I might accept PKCS#8
v2 for RSAPrivateKey and ECPrivateKey and verify that publicKey
exactly matches the copy of the public key stored in privateKey.

For key types specified in this draft, I will provide a flag where the
user indicates whether they want to require the pairwise consistency
check to pass. If the flag is "no consistent check needed" then I will
accept v1 (with no publicKey). Otherwise if the flag is "consistency
check needed" then I will only accept v2 where the publicKey field is
present and consistent with the private key.

Cheers,
Brian
-- 
https://briansmith.org/

---

From: Brian Smith <[email-masked]>
Date: Sun, 7 May 2017 13:34:28 -1000

Jim Schaad <[email-masked]> wrote:
> In particular, it is important for the spec to include v2 PKCS#8 examples
> with the publicKey field, if such encoding is allowed.
>
> [JLS] This is a reasonable request.  I will look at adding this as part of
> the IETF last call comments.

Here are four test vectors for Ed25519 PKCS#8 v2 keys (with the public
key included) that I would like to have added to the RFC.

PKCS#8 V2. The private key starts with a zero byte.
-----BEGIN PRIVATE KEY-----
3053020101300506032b65700422042000b1a7c20b2b4ed9c78f3686db82
f854734cdc95be51def304d98e0cd30bf490a12303210063457cd4dfdd0e
98a53796265831d46ac6a5a685f2a54c9697a38b2c800d60ba
-----END PRIVATE KEY-----

PKCS#8 V2. The private key ends with a zero byte.
-----BEGIN PRIVATE KEY-----
3053020101300506032b657004220420a22efdb713f0e1600d2a5ce948e3
21ca3a18137c47f15091a12c7126c1749a00a1230321001aeb8e3ee5ba5a
fd91113466d19f4ea77fa0feffbd8c5adcb499927f12535f77
-----END PRIVATE KEY-----

PKCS#8 V2. The public key starts with a zero byte.
-----BEGIN PRIVATE KEY-----
3053020101300506032b6570042204202dc67de5186d9193021c0b104d9c
6ef24bee2bd395ccb5ed5a2db5f37a2fc1f0a12303210000c17e4d8bbff2
7c1fb618c23fce988703c7efa3cd590aacac12d3f1e3c90c8c
-----END PRIVATE KEY-----

PKCS#8 V2. The public key ends with a zero byte.
-----BEGIN PRIVATE KEY-----
3053020101300506032b657004220420b2579f555a2eabdabac8d46997b1
c08fe8ce63858df124efc29c60dfbb86c349a1230321009d421270ce2fcc
08672c41e427214876245c9b0f14ab671b8bb9d266a492e400
-----END PRIVATE KEY-----

Cheers,
Brian

---

From: Brian Smith <[email-masked]>
Date: Sun, 7 May 2017 13:46:03 -1000

Let me try again, this time using the same encoding that is used in
the RFC (Base64):

Here are 5 examples of v2 PKCS#8 Ed25519 private keys, with the public
key included, that I'd like to have included in the RFC as test
vectors. The first four examples are valid (I hope!) and 5th example
is invalid.

Ed25519 PKCS#8 v2. The first byte of the private key is zero:
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIACxp8ILK07Zx482htuC+FRzTNyVvlHe8wTZjgzTC/SQoS
MDIQBjRXzU390OmKU3liZYMdRqxqWmhfKlTJaXo4ssgA1gug==
-----END PRIVATE KEY-----

Ed25519 PKCS#8 v2. The last byte of the private key is zero:
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoS
MDIQAa644+5bpa/ZERNGbRn06nf6D+/72MWty0mZJ/ElNfdw==
-----END PRIVATE KEY-----

Ed25519 PKCS#8 v2. The first byte of the public key is zero:
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIC3GfeUYbZGTAhwLEE2cbvJL7ivTlcy17VottfN6L8HwoS
MDIQAAwX5Ni7/yfB+2GMI/zpiHA8fvo81ZCqysEtPx48kMjA==
-----END PRIVATE KEY-----

Ed25519 PKCS#8 v2. The last byte of the public key is zero:
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEILJXn1VaLqvausjUaZexwI/ozmOFjfEk78KcYN+7hsNJoS
MDIQCdQhJwzi/MCGcsQeQnIUh2JFybDxSrZxuLudJmpJLkAA==
-----END PRIVATE KEY-----

INVALID Ed25519 PKCS#8 v2. The last byte of the public key has
had its high bit flipped. (In Ed25519 the high bit of the public key is
not masked as in X25519.)
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEILJXn1VaLqvausjUaZexwI/ozmOFjfEk78KcYN+7hsNJoS
MDIQCdQhJwzi/MCGcsQeQnIUh2JFybDxSrZxuLudJmpJLkgA==
-----END PRIVATE KEY-----

Cheers,
Brian

---

From: Brian Smith <[email-masked]>
Date: Sun, 7 May 2017 19:39:57 -1000

> vectors. The first four examples are valid (I hope!) and 5th example

Here are 4 pairs of example X25519 PKCS#8 v2 keys. The first key in
each pair has its public key's high bit clear. The second key in each
pair is the same except it has its public key's high bit set.

The private key ends with a zero byte. The public key's high bit
is zero.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoS
MDIQDliXC2h2mPYSA5LxgZtiSnFyycrsQrC/N4W0DGBswoYA==
-----END PRIVATE KEY-----

The private key is the same as the previous one. The public key is
also the same except its high bit is one.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoS
MDIQDliXC2h2mPYSA5LxgZtiSnFyycrsQrC/N4W0DGBswo4A==
-----END PRIVATE KEY-----

The private key starts with a zero byte. The public key's high bit
is zero.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIACxp8ILK07Zx482htuC+FRzTNyVvlHe8wTZjgzTC/SQoS
MDIQDU7K6GMlleypYW/dhAD/Lp4LZakMUufAZu5j0+0YweBw==
-----END PRIVATE KEY-----

The private key is the same as the previous one. The public key is
also the same except its high bit is one.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIACxp8ILK07Zx482htuC+FRzTNyVvlHe8wTZjgzTC/SQoS
MDIQDU7K6GMlleypYW/dhAD/Lp4LZakMUufAZu5j0+0Ywehw==
-----END PRIVATE KEY-----

The public key starts with a zero byte. The public key's high bit
is zero.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEILk6+PsBTElrUDbktWya6voRhmEjk7/6kA3NocUxR5yAoS
MDIQAAO3q2kQKshYA5ywap42py7uq0Sx751hwGgeQUcC3/Dw==
-----END PRIVATE KEY-----

The private key is the same as the previous one. The public key is
also the same except its high bit is one.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEILk6+PsBTElrUDbktWya6voRhmEjk7/6kA3NocUxR5yAoS
MDIQAAO3q2kQKshYA5ywap42py7uq0Sx751hwGgeQUcC3/jw==
-----END PRIVATE KEY-----

The public key ends with a zero byte, and thus its high bit is
zero.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIHLXzckbjCm4crsB85VeSSH7kxonnTnUMO+QfBbe2JVIoS
MDIQCZxD/fCNjPVwXxYAKr8DhD7Vw0q8PrhpvXW5j2krCYAA==
-----END PRIVATE KEY-----

The private key is the same as the previous one. The public key is
also the same except its high bit is one.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIHLXzckbjCm4crsB85VeSSH7kxonnTnUMO+QfBbe2JVIoS
MDIQCZxD/fCNjPVwXxYAKr8DhD7Vw0q8PrhpvXW5j2krCYgA==
-----END PRIVATE KEY-----

Cheers,
Brian
--
https://briansmith.org/

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 8 May 2017 11:38:57 +0300

> vectors. The first four examples are valid (I hope!) and 5th example

<snip some test vectors>

In case you want these, I did the corresponding vectors for Ed448
(using the reference implementation). I also included example PKCS#8v1
and public key (hopefully these are correct, I do have TLS library
capable of handling Ed448 keys, but it can't load this format, and
writing key module code for it would be a bit nontrivial):

Ed448 private key (from the first test vector in RFC8032):
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOWyCpWLLgI0Q1jK+ichRPr9skp803fqMn2PJlg7240ijUoyKP8wvBE45
o/xblEkvjwMudUmiAJj5Ww==
-----END PRIVATE KEY-----

Dumped as asn1:
    0 30   71: SEQUENCE {
    2 02    1:   INTEGER 0
    5 30    5:   SEQUENCE {
    7 06    3:     OBJECT IDENTIFIER
             :       EdDSA 448 signature algorithm { 1 3 101 113 }
             :     }
   12 04   59:   OCTET STRING
             :     04 39 6C 82 A5 62 CB 80 8D 10 D6 32 BE 89 C8 51
             :     3E BF 6C 92 9F 34 DD FA 8C 9F 63 C9 96 0E F6 E3
             :     48 A3 52 8C 8A 3F CC 2F 04 4E 39 A3 FC 5B 94 49
             :     2F 8F 03 2E 75 49 A2 00 98 F9 5B
             :   }

Note that the value of the private key is:

6C 82 A5 62 CB 80 8D 10 D6 32 BE 89 C8 51 3E BF
6C 92 9F 34 DD FA 8C 9F 63 C9 96 0E F6 E3 48 A3
52 8C 8A 3F CC 2F 04 4E 39 A3 FC 5B 94 49 2F 8F
03 2E 75 49 A2 00 98 F9 5B

Ed448 public key (the first test vector in RFC8032):

Public Key Information:
    Public Key Algorithm: EdDSA448
    Algorithm Security Level: Ultra

Public Key Usage:

Public Key ID: 3a04967761a552db7e9e18c6dba4bd4aae119908
-----BEGIN PUBLIC KEY-----
MEMwBQYDK2VxAzoAX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2m0bHBhvWeD3x
5Q9s0foavq/oJWGA
-----END PUBLIC KEY-----

Ed448 PKCS#8 v2. The first byte of the private key is zero:
-----BEGIN PRIVATE KEY-----
MIGFAgEBMAUGAytlcQQ7BDkAlY2VelwSNc5qN87ewXgVx3poDdR0OdqYyo/uBy4bnWEwDLG3dHXO
p+usJ1j3LxKJXlLXuR1HeQahPAM6APhztQF4TM64dZqkG41k/xfFx8cD346La7OO3tdx1s7eWRnh
/D+8vavt+fTgtDVtKgNq9hGF7z3YgA==
-----END PRIVATE KEY-----

Ed448 PKCS#8 v2. The last byte of the private key is zero:
-----BEGIN PRIVATE KEY-----
MIGFAgEBMAUGAytlcQQ7BDmB0i639YAUIxrkaJKyasoRPI/sVNywUPCC2G6LFgMH6u4K5aEaOH2m
BQ4BPulPRikPE0RqH+M/yAChPAM6AO45hh9/sUCg4JD4SIOZmB4eBBemoVXmDp/U95GzOnE1oIgf
TWQErk0VdzozIHu4AsIqup3RIZ7PAA==
-----END PRIVATE KEY-----

Ed448 PKCS#8 v2. The first byte of the public key is zero:
-----BEGIN PRIVATE KEY-----
MIGFAgEBMAUGAytlcQQ7BDn7w37WCHYkgzuWFxIp9s1UZdjBRWLCHQErJnYslwhzgarOZ4p5EnP5
JnC6y0q9FnZ/vaaqdgZSOVOhPAM6AAChrpHbZRZwBDZttZ5zgsK6WSL2jG+gOdwUITv0nOZ8wwv8
NTJ+CDurgoxzllC9o5V22p5f2LDKgA==
-----END PRIVATE KEY-----

Ed448 PKCS#8 v2. The last byte of the public key is zero:
-----BEGIN PRIVATE KEY-----
MIGFAgEBMAUGAytlcQQ7BDluPRT8xhEhgC+tSgkBXH/NcJ3rQcjQwuHuz4C3yoHa8dxx3rl5AoLs
+Msa6yepMSM8szmmA3tDHhWhPAM6AAwjssedathfb9G4JZl44MHQrenIavuVLx7WGWlAyizxOICd
OlNhiNnaG9X82sCHapbYur9B2M7aAA==
-----END PRIVATE KEY-----

INVALID Ed448 PKCS#8 v2. The last byte of the public key has
had its high bit flipped. (In Ed448 the public key has an extra byte not
present in X448.)
-----BEGIN PRIVATE KEY-----
MIGFAgEBMAUGAytlcQQ7BDmO9WySfQhRwpCdsECXiaxQAkMNe9QX2SApkWvjLMw07mXmtIFRWj0+
TblePrcgZtjcDVGCXfj+JgGhPAM6AFWgw4BsOzoCCGWud8wIhJnVVsxQXGqUPO+KySrQKzgR7Vnn
r4JiAANv2azdo57L52bQB3wmjqLbAA==
-----END PRIVATE KEY-----

-Ilari

---

From: Jim Schaad <[email-masked]>
Date: Mon, 8 May 2017 10:27:55 -0700

From: David Benjamin [mailto:[email-masked]] 
Sent: Monday, May 1, 2017 9:15 AM
To: Brian Smith <[email-masked]>; Jim Schaad <[email-masked]>
Cc: curdle <[email-masked]>
Subject: Re: [Curdle] FW: New Version Notification for draft-ietf-curdle-pkix-04.txt

On Sun, Apr 30, 2017 at 8:17 PM Brian Smith <[email-masked] <mailto:[email-masked]> > wrote:

Jim Schaad <[email-masked] <mailto:[email-masked]> > wrote:
> It is not always possible to detect corruption when you store in an unencrypted form.

> It would also not be possible to know if it was the private key or the public key that has been corrupted, just that the two values do not match.

(Not that it matters, but, to that end, would detecting corruption not be just as easily served by stashing a checksum somewhere? If not external to the serialization, there is already that attributes field.)

As the author of one such PKCS#8 implementation, I'd simply missed that v2 PKCS#8 existed. Happy to add support (by way of ignoring the field probably, yeah). Lacking any useful text about what to do, I interpreted the version field to be analogous to RSAPrivateKey, another PKCS spec. There, an RFC 2437 implementation that attempted to be forwards-compatible (by accepting unknown versions and ignoring appended fields) would have been confused come RFC 3447, which decided v1 meant a semantically-incompatible otherPrimeInfos field.

RFC 5958 continues this. It does use ASN.1 extension markers, but X.680 merely says "The action that is taken in each situation is determined by the ASN.1 specifier", and RFC 5958 does not appear to say anything.

Is the intent that OneAsymmetricKey parsers accept a hypothetical v3 with further appended fields, or should they reject those to allow for RFC-3447-like changes? If so, how do they handle the version <=> extra field correspondence? A numerical comparison? Assume all unknown values are newer? The version number used in the ASN.1 tags corresponds to the symbolic name of the version constants, rather than the numerical value, so it's not obvious whether, say, defining v3(-1) would be acceptable.

[JLS] I had thought this was going to be an easy answer, but as I did not have any of my ASN.1 documents with me last week I decided to defer responding until I retrieved them from the backup drives.  I am happy that I did as what I thought was the correct answer isn’t.  I had always thought that the rules were that any additional fields could be ignored by a prior parser when evaluating the content of the decoded object.  The answer from the X.680 is – it depends.  

I guess that people are supposed to define what the correct behavior for this is when they put the extensibility flag into an ASN.1 structure.  We did not do this when we wrote the document for OneSymmetricKey and we should have done so.  From what we were doing, I would say that the answer is that all future fields can be ignored when parsing one of these structures.  This is the philosophy that was adopted for dealing with unknown attributes.  It would make sense to file an Errata to this end on RFC 5958 so that we can make sure that this says the expected method of doing thigs.

Jim

David

---

From: David Benjamin <[email-masked]>
Date: Mon, 08 May 2017 18:06:16 +0000

On Mon, May 8, 2017 at 1:27 PM Jim Schaad <[email-masked]> wrote:

> *From:* David Benjamin [mailto:[email-masked]]
>
> *Sent:* Monday, May 1, 2017 9:15 AM
> *To:* Brian Smith <[email-masked]>; Jim Schaad <
> [email-masked]>
>
>
> *Cc:* curdle <[email-masked]>
> *Subject:* Re: [Curdle] FW: New Version Notification for
> draft-ietf-curdle-pkix-04.txt
>
>
>
> [JLS] I had thought this was going to be an easy answer, but as I did not
> have any of my ASN.1 documents with me last week I decided to defer
> responding until I retrieved them from the backup drives.  I am happy that
> I did as what I thought was the correct answer isn’t.  I had always thought
> that the rules were that any additional fields could be ignored by a prior
> parser when evaluating the content of the decoded object.  The answer from
> the X.680 is – it depends.
>
>
>
> I guess that people are supposed to define what the correct behavior for
> this is when they put the extensibility flag into an ASN.1 structure.  We
> did not do this when we wrote the document for OneSymmetricKey and we
> should have done so.  From what we were doing, I would say that the answer
> is that all future fields can be ignored when parsing one of these
> structures.  This is the philosophy that was adopted for dealing with
> unknown attributes.  It would make sense to file an Errata to this end on
> RFC 5958 so that we can make sure that this says the expected method of
> doing thigs.
>

That works for me. What would you then say is the intended interpretation
of the version field? Going from PrivateKeyInfo to OneAsymmetricKey makes
sense to bump the version because it is arguably a semi-incompatible
change. (And, regardless, it's too late to undo that.) I would maybe argue
that future versions of OneAsymmetricKey should *not* bump the version
number. It's not clear to me it serves any purpose in this context since a
parser can't do anything useful with unknown values. So perhaps:

- When serializing without publicKey, serializing code SHOULD use v1
(PrivateKeyInfo). v2 (OneAsymmetricKey) would also work, but this will be
less compatible.
- When serializing with publicKey, serializing code MUST use v2,
- When parsing and the version is v1, parse as PrivateKeyInfo (i.e.
non-extensible and publicKey does not exist).
- When parsing and the version is v2, parse as OneAsymmetricKey. When
parsing as OneAsymmetricKey, one MUST ignore trailing fields after the
OPTIONAL publicKey.
- When parsing and the version is anything else, reject. This is some
invalid thing.

I'm also equally fine with some variant of Brian's stricter interpretation,
which effectively means removing the X.680 extensibility markers. I don't
think this is a context where extensibility is needed and, regardless,
we've already got that attributes field. (OneAsymmetricKey itself could
probably have been skipped in favor of defining a publicKey attribute.)

David

---

From: Brian Smith <[email-masked]>
Date: Mon, 8 May 2017 08:42:45 -1000

Jim Schaad <[email-masked]> wrote:
> David Benjamin wrote:
>> merely says "The action that is taken in each situation is determined by the
>> ASN.1 specifier", and RFC 5958 does not appear to say anything.

> did not do this when we wrote the document for OneSymmetricKey and we should
> have done so.  From what we were doing, I would say that the answer is that
> all future fields can be ignored when parsing one of these structures.  This
> is the philosophy that was adopted for dealing with unknown attributes.  It
> would make sense to file an Errata to this end on RFC 5958 so that we can
> make sure that this says the expected method of doing thigs.

I would rather it not use the extensibility feature of ASN.1. My
understanding is that if one doesn't use the extensibility feature,
then "dumb" parsers like mine and the one in BoringSSL work fine. Once
you start using the extensibility feature, creating a correct parser
becomes more difficult. And we don't need the flexibility anyway,
since PKCS#8 v1 already defined an extensibility mechanism
(attributes). That is, we shouldn't have a v2 at all, nor the
publicKey field, but instead should have used attributes. Whatever we
do with v2 and publicKey now is about coping with the fact that v2 is
already defined. Going forward, extensibility should be handled with
attributes, so I expect no new versions to be defined.

Cheers,
Brian
-- 
https://briansmith.org/

---

From: Brian Smith <[email-masked]>
Date: Mon, 8 May 2017 08:46:17 -1000

RFC 5958 says:
> version identifies the version of OneAsymmetricKey.  If publicKey
> is present, then version is set to v2 else version is set to v1.

This means if the publicKey is present, version MUST be v2. When
publicKey is absent, version MUST be v1. (This is what we want, for
interop with older implementations.)

> parsing as OneAsymmetricKey, one MUST ignore trailing fields after the

I would rather not ignore trailing fields after publicKey.

> - When parsing and the version is anything else, reject. This is some

Yep, I agree.

Cheers,
Brian
-- 
https://briansmith.org/

---

From: David Benjamin <[email-masked]>
Date: Mon, 08 May 2017 18:54:54 +0000

> interop with older implementations.)

Ah, I'd missed that. Yeah, being tighter's even better.

> I would rather not ignore trailing fields after publicKey.

Just to clarify, my comment was intended as a proposed concrete version of
what Jim was saying. I am also fine with (and probably prefer) your version
where we punt the X.680-level extensibility. But I also don't care much and
just want there to be *some* concrete interpretation. :-)

---

From: Brian Smith <[email-masked]>
Date: Tue, 9 May 2017 15:31:51 -1000

Here are some more test vectors for INVALID edge cases of Ed25519 and
X25519 PKCS#8 v2 keys that I would like to have included in the RFC.

Ed25519 INVALID. The first byte of the public key, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VwBCIEIC3GfeUYbZGTAhwLEE2cbvJL7ivTlcy17VottfN6L8HwoS
IDIADBfk2Lv/J8H7YYwj/OmIcDx++jzVkKrKwS0/HjyQyM
-----END PRIVATE KEY-----

Ed25519 INVALID. The last byte of the public key, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VwBCIEILJXn1VaLqvausjUaZexwI/ozmOFjfEk78KcYN+7hsNJoS
IDIACdQhJwzi/MCGcsQeQnIUh2JFybDxSrZxuLudJmpJLk
-----END PRIVATE KEY-----

Ed25519 INVALID. The first byte of the private key, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VwBCEEH7GnwgsrTtnHjzaG24L4VHNM3JW+Ud7zBNmODNML9JChIw
MhAGNFfNTf3Q6YpTeWJlgx1GrGpaaF8qVMlpejiyyADWC6
-----END PRIVATE KEY-----

Ed25519 INVALID. The last byte of the private key, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VwBCEEH6Iu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJqhIw
MhABrrjj7lulr9kRE0ZtGfTqd/oP7/vYxa3LSZkn8SU193
-----END PRIVATE KEY-----

Ed25519 INVALID. The version is v1 but the publicKey field is included.
-----BEGIN PRIVATE KEY-----
MFMCAQAwBQYDK2VwBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoS
MDIQAa644+5bpa/ZERNGbRn06nf6D+/72MWty0mZJ/ElNfdw==
-----END PRIVATE KEY-----

Ed25519 INVALID. The version is v2 but the publicKey field is missing.
-----BEGIN PRIVATE KEY-----
MC4CAQEwBQYDK2VwBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoA
-----END PRIVATE KEY-----

Ed25519 INVALID. The publicKey field is indicated with [0] instead of [1];
i.e. the attributes are invalid and publicKey is missing.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoC
MDIQAa644+5bpa/ZERNGbRn06nf6D+/72MWty0mZJ/ElNfdw==
-----END PRIVATE KEY-----

X25519 INVALID. The private key's last byte, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VuBCEEH6Iu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJqhIw
MhAOWJcLaHaY9hIDkvGBm2JKcXLJyuxCsL83hbQMYGzChg
-----END PRIVATE KEY-----

X25519 INVALID. The private key's first byte, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VuBCEEH7GnwgsrTtnHjzaG24L4VHNM3JW+Ud7zBNmODNML9JChIw
MhANTsroYyWV7Klhb92EAP8ungtlqQxS58Bm7mPT7RjB4H
-----END PRIVATE KEY-----

X25519 INVALID. The public key's first byte, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VuBCIEILk6+PsBTElrUDbktWya6voRhmEjk7/6kA3NocUxR5yAoS
IDIAA7eraRAqyFgDnLBqnjanLu6rRLHvnWHAaB5BRwLf8P
-----END PRIVATE KEY-----

X25519 INVALID. The public key's last byte, zero, is omitted.
-----BEGIN PRIVATE KEY-----
MFICAQEwBQYDK2VuBCIEIHLXzckbjCm4crsB85VeSSH7kxonnTnUMO+QfBbe2JVIoS
IDIACZxD/fCNjPVwXxYAKr8DhD7Vw0q8PrhpvXW5j2krCY
-----END PRIVATE KEY-----

X25519 INVALID. The version is v1 but it has a publicKey field.
-----BEGIN PRIVATE KEY-----
MFMCAQAwBQYDK2VuBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoS
MDIQDliXC2h2mPYSA5LxgZtiSnFyycrsQrC/N4W0DGBswoYA==
-----END PRIVATE KEY-----

X25519 INVALID. The publicKey field is indicated with [0] instead of [1];
i.e. the attributes are invalid and publicKey is missing.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoAoC
MDIQDliXC2h2mPYSA5LxgZtiSnFyycrsQrC/N4W0DGBswoYA==
-----END PRIVATE KEY-----

X25519 INVALID. The version is v2 but there is no publicKey field.
-----BEGIN PRIVATE KEY-----
MC4CAQEwBQYDK2VuBCIEIKIu/bcT8OFgDSpc6UjjIco6GBN8R/FQkaEscSbBdJoA
-----END PRIVATE KEY-----

Cheers,
Brian

-- 
https://briansmith.org/

---

From: Jim Schaad <[email-masked]>
Date: Wed, 10 May 2017 07:21:31 -0700

I have not yet gotten to the point of validating the edge cases, although the number seems to be getting to the point of a test suite which I would prefer to handle in a different manner.

I have been reading the curve drafts and looking at my implementation to try and figure out what the rules are and what the implications are relative to what is being asked for.

Public keys - I think that it makes sense to talk about saying that checks needs to be done on public keys.  For the set of checks I can just reference the two drafts, I do not think that I need to re-state them in this draft.

Private keys - There is a slightly interesting trade-off that may need to be considered at this point.  One can either have the keys in the correct format, or one can require that the correct masking be applied during the import step.  The reason for requiring the latter is that it removes some of the fixed structure of the private key.  This has a (very small) advantage as a totally random item is harder to make guesses at.  It is true however that there is other structure in the text that is encrypted so this would be a very small advantage.  When I wrote my code, I did the import and then the masking step as the masking needs to be done in a lot of cases when operations are done.  Do people have opinions on this?

OneAsymmetricKey version numbering - I am looking at putting some guidance text on this into the document.  I will send it out once I am happy with it.

Jim

-----END PRIVATE KEY-----

Ed25519 INVALID. The publicKey field is indicated with [0] instead of [1]; i.e. the attributes are invalid and publicKey is missing.

-----END PRIVATE KEY-----

X25519 INVALID. The publicKey field is indicated with [0] instead of [1]; i.e. the attributes are invalid and publicKey is missing.

-----END PRIVATE KEY-----

Cheers,
Brian

On Sun, May 7, 2017 at 7:39 PM, Brian Smith <[email-masked]> wrote:
>> Here are 5 examples of v2 PKCS#8 Ed25519 private keys, with the 
>> public key included, that I'd like to have included in the RFC as 
>> test vectors. The first four examples are valid (I hope!) and 5th 
>> example is invalid.
>
> The private key ends with a zero byte. The public key's high bit is 
> zero.
> The private key starts with a zero byte. The public key's high bit is 
> zero.
> The public key starts with a zero byte. The public key's high bit is 
> zero.
> The public key ends with a zero byte, and thus its high bit is zero.

--
https://briansmith.org/

---

From: Russ Housley <[email-masked]>
Date: Wed, 10 May 2017 13:44:13 -0400

> OneAsymmetricKey version numbering - I am looking at putting some guidance text on this into the document.  I will send it out once I am happy with it.

The handling of version numbers in CMS works with the most primitive ASN.1 tools.  I think that approach should be followed here too.

Russ

---

From: Brian Smith <[email-masked]>
Date: Wed, 10 May 2017 12:17:31 -1000

Here are some test vectors for X25519 private key bit masking, where
each vector is a valid PKCS#8 v2 file. These tests every combination
of high and low bits for an all-ones private key. The masked private
key is the same for each case and thus the public key is the same for
each case. Please incorporate all these into the RFC as test vectors,
in addition to all the ones I previously posted.

Note that the same kind of test cannot be done for Ed25519, because in
Ed25519 PKCS#8 files the private key field is the seed that is hashed
with SHA-512 to get the actual private key scalar; i.e. for Ed25519 it
isn't the PKCS#8 file's privateKey field that gets masked, but rather
an intermediate value.

X25519 with private key high bits 0b00, low bits 0b000.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPj///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b001.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPn///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b010.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPr///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b011.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPv///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b100.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPz///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b101.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP3///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b110.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP7///////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b00, low bits 0b111.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP////////////////////////////////////////8/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b000.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPj///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b001.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPn///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b010.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPr///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b011.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPv///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b100.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPz///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b101.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP3///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b110.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP7///////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b01, low bits 0b111.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP////////////////////////////////////////9/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b000.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPj///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b001.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPn///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b010.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPr///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b011.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPv///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b100.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPz///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b101.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP3///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b110.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP7///////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b10, low bits 0b111.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP////////////////////////////////////////+/oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b000.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPj/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b001.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPn/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b010.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPr/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b011.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPv/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b100.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIPz/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b101.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP3/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b110.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP7/////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

X25519 with private key high bits 0b11, low bits 0b111.
-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VuBCIEIP//////////////////////////////////////////oS
MDIQCEfA0sN1I082XmYJVRh6NzWg92E9FgnTpqTYxTrqpaIg==
-----END PRIVATE KEY-----

Cheers,
Brian

-- 
https://briansmith.org/

---

From: Brian Smith <[email-masked]>
Date: Wed, 10 May 2017 12:23:12 -1000

> I have not yet gotten to the point of validating the edge cases, although the number seems to be getting to the point of a test suite which I would prefer to handle in a different manner.

I would prefer the test suite to be incorporated into the RFC, and for
it to be considered normative.

> Public keys - I think that it makes sense to talk about saying that checks needs to be done on public keys.  For the set of checks I can just reference the two drafts, I do not think that I need to…

It would be good to see the text that will be used. I personally agree
that consistency of the private and public key MUST/SHOULD be checked,
but others may disagree.

More importantly, there should be a requirement that the v2 form (with
the public key) must be accepted.

> Private keys - There is a slightly interesting trade-off that may need to be considered at this point.  One can either have the keys in the correct format, or one can require that the correct maski…

Every possible 32-byte private key should be accepted, and the
implementation should mask the input after parsing the privateKey
value and before doing the pairwise consistency check (if any) and
before doing any operation using the private key. See my other reply
where I provide test vectors for this.

Cheers,
Brian
--
https://briansmith.org/

---

From: David Benjamin <[email-masked]>
Date: Wed, 10 May 2017 22:47:38 +0000

On Wed, May 10, 2017 at 6:23 PM Brian Smith <[email-masked]> wrote:

> > I have not yet gotten to the point of validating the edge cases,
> although the number seems to be getting to the point of a test suite which
> I would prefer to handle in a different manner.
>
> > Public keys - I think that it makes sense to talk about saying that
> checks needs to be done on public keys.  For the set of checks I can just
> reference the two drafts, I do not think that I need to re-state them in
> this draft.
>

I think requiring the consistency check here is excessive. You're now
requiring everyone compute it, which means there was no point in including
it to begin with.

Yes, it provides a corruption check, but a rather convoluted one, as this
thread demonstrates. You've got problems with high bits being set, etc. I
think folks who care about detecting corruption should add an external
checksum to wherever they're getting their keys from. That is simpler,
works uniformly for all key types, and avoids raising questions like "why
aren't you doing a consistency check on the attributes?".

If an application needs both corruption detection *and* is incapable of
adding it to the layer above, this is so specific a use case that requiring
everyone do it does not make sense. If we really believed this should be
universal to private key transport, we would have defined every private key
format in the world to be K || hash(K).

Instead, I would recommend serving that use case by defining a checksum
attribute type in a separate document and getting it standardized.

I don't especially object to requiring the v2 form be accepted or fixing
BoringSSL to accept it, but if the only use is a mandatory convoluted
checksum check, then I would rather we throw v2 away and stick with the
simple thing.

> > Private keys - There is a slightly interesting trade-off that may need
> to be considered at this point.  One can either have the keys in the
> correct format, or one can require that the correct masking be applied
> during the import step.  The reason for requiring the latter is that it
> removes some of the fixed structure of the private key.  This has a (very
> small) advantage as a totally random item is harder to make guesses at.  It
> is true however that there is other structure in the text that is encrypted
> so this would be a very small advantage.  When I wrote my code, I did the
> import and then the masking step as the masking needs to be done in a lot
> of cases when operations are done.  Do people have opinions on this?
>
> _______________________________________________
> Curdle mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/curdle
>

---

From: Jim Schaad <[email-masked]>
Date: Wed, 10 May 2017 15:59:37 -0700

Sent: Wednesday, May 10, 2017 3:48 PM

On Wed, May 10, 2017 at 6:23 PM Brian Smith <[email-masked] <mailto:[email-masked]> > wrote:

I think requiring the consistency check here is excessive. You're now requiring everyone compute it, which means there was no point in including it to begin with.

Yes, it provides a corruption check, but a rather convoluted one, as this thread demonstrates. You've got problems with high bits being set, etc. I think folks who care about detecting corruption should add an external checksum to wherever they're getting their keys from. That is simpler, works uniformly for all key types, and avoids raising questions like "why aren't you doing a consistency check on the attributes?".

If an application needs both corruption detection *and* is incapable of adding it to the layer above, this is so specific a use case that requiring everyone do it does not make sense. If we really believed this should be universal to private key transport, we would have defined every private key format in the world to be K || hash(K).

Instead, I would recommend serving that use case by defining a checksum attribute type in a separate document and getting it standardized.

I don't especially object to requiring the v2 form be accepted or fixing BoringSSL to accept it, but if the only use is a mandatory convoluted checksum check, then I would rather we throw v2 away and stick with the simple thing.

[JLS] I was not looking at public keys in the private key blob, but public keys in the certificate.

Jim

Cheers,
Brian
--
https://briansmith.org/

_______________________________________________
Curdle mailing list
[email-masked] <mailto:[email-masked]> 
https://www.ietf.org/mailman/listinfo/curdle

---

From: Brian Smith <[email-masked]>
Date: Wed, 10 May 2017 13:02:15 -1000

> checksum check, then I would rather we throw v2 away and stick with the

Besides being a checksum against corruption, here are the benefits
I've found to having the public key in the file:

* It protects against the case where the producer of the private key
miscalculated the public key (i.e. the producer's math is buggy).

* It protects against the case where the consumer of the private key
miscalculates the public key (i.e. the consumer's math is buggy).

* If you have (a lot of) PKCS#8 documents, you can look up a private
key by public key without having to compute the public key from the
private key for each one.

* If an implementation presents the public key as it is stored in the
PKCS#8 file, then the public key will always be present consistently.
That is, it provides a way to avoid implementation fingerprinting,
although it doesn't mandate implementations try to avoid
fingerprinting in this way.

Note that RFC 5915 (ECPrivateKey for traditional curves) doesn't
require publicKey to be present and it doesn't require the user to
check that the private key is consistent with the public key even when
it is present. And other standards for those curves also do provide
alternatives (see, for example, NIST SP 800-56A section 5.6.3.2). So I
agree that saying that the implementation MUST do the check is
excessive, but I do think it is a really good idea.

Cheers,
Brian
--
https://briansmith.org/