Subject: [Spasm] Best practices for applications using X.509 client certificates

From: David Woodhouse <[email-masked]>
Date: Mon, 19 Sep 2016 11:23:21 +0100

(I hope the cross-post is acceptable; apologies if not.)

Various applications will optionally make use of X.509 certificates for
client authentication.

Those certificates, and the associated private keys, may be found in
files on the file system, in PKCS#11 tokens, or in another
OS-specific form of certificate database.

In my opinion, it would be nice to have some consistency between
applications. If a user has a certificate in a certain form, it would
be nice for that to Just Work™ across all well-behaved applications.

In practice, nothing could be further from the truth.

Applications *all* suck, and various certificates will spuriously fail
to work in one application but not another. Or work if the application
is build against crypto library $A but not when built against crypto
library $B. Or for objects in PKCS#11 each application might require a
*different* identifier string to locate the same object. If they
support PKCS#11 at all.

I'd like to fix that. I would like to achieve a consensus that a "well-
behaved application" SHOULD accept certificates and keys in various
(TBD) file formats and also accept PKCS#11 URIs according to RFC7512.

I have slowly been working on this. I have encouraged the Fedora
distribution of Linux to amend their packaging guidelines to state that
software packaged for Fedora SHOULD accept a PKCS#11 URI wherever it
would accept a filename. And that software SHOULD load the PKCS#11
tokens which are indicated by the system configuration.

We have already fixed various applications to comply with these
requirements, and I even mentored a Google Summer of Code project which
added RFC7512 support to NSS².

I believe the Fedora packaging guidelines have been a success, and I
would like to expand the scope. There's no *reason* this should be
Fedora-specific, or even specific to Linux or POSIX operating systems.
So I'm looking for a forum in which to reach a consensus on what should
be accepted, and to publish those guidelines. I'd be very interested in
hearing suggestions.

Simultaneously, I'm also looking at expanding the technical scope.
For my own project, the OpenConnect VPN client, I have started to
collect a torture test suite³ of RSA, DSA and EC keys in various
PKCS#1, PKCS#8 and PKCS#12 forms — both unencrypted, and encrypted with
various algorithms. I have yet to embark of the joy of files with non-
ASCII passphrases, especially in non-UTF8 locales — but I have a bottle
of vodka ready to help me do so.

My test suite also includes PKCS#11 tests including private keys where
the token doesn't expose the public component (which made OpenSSL crash
until yesterday, yay!) and certificates with the CKA_PRIVATE attribute
set, so some software will fail to *find* them.

I am thinking of splitting my torture test out from OpenConnect itself,
and making it available as a project in its own right.

I can, of course, lobby to expand the Fedora guidelines to state that
all software packaged for Fedora SHOULD pass the torture test suite,
but I think it makes sense to aim for a wider consensus than that.

Opinions welcome... does it make sense to attempt to publish an
informational RFC outlining such "expectations"? Or should it take some
other form? Or should I just not bother, and continue to push it from
the Fedora angle, since it's getting into a lot of upstream software
already?

I also expect some heckling at my specific test cases — do we *really*
expect everyone to support DSA keys still? And PEM files encrypted the
old OpenSSL way? And PKCS#12 files encrypted with MD5-DES?

(I can accept 'no' answers to the latter two only if expressed in a
form which lets me file bugs against ancient "enterprise" software to
stop *creating* them that way...)

-- 
dwmw2

¹ https://fedoraproject.org/wiki/Packaging:SSLCertificateHandling
² https://bugzil.la/1162897
³ http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/tests/Makefile.am

---

From: Ted Lemon <[email-masked]>
Date: Mon, 19 Sep 2016 07:26:14 -0400

The effort is certainly worth doing.   I've encountered the same problem,
and also find it frustrating.   It might be worth writing an informational
doc; the challenge would be socializing it to the people who need to read
it.

On Mon, Sep 19, 2016 at 6:23 AM, David Woodhouse <[email-masked]>
wrote:

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

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Mon, 19 Sep 2016 12:35:07 -0400

This is a very common problem and one that I encounter on an hourly basis
as I write code for the Mesh. There are three separate formats used for
public keys in SSH and four for private.

This is all stuff that has dropped off the table as far as the standards
groups are concerned because 'it isn't protocol that goes on the wire'.
Except of course it does.

The way I think we have to approach a solution is to use a container of
some type whether that is MIME or JSON that has a slot for metadata
describing the content type to follow:

Content-Type: application/pkix-certificate
Content-Encoding: BASE64

3ljkrf3kjrkj3hrfkjh3fjkh3jkfh34fkjh==

It isn't too difficult to allow a choice of MIME or JSON for the container
as the JSON will always start with a { and the MIME never will.

I use JSON-B which is simply JSON with an added code point that lets me
drop specified length binary encoded data into a JSON document at a
particular point. But that is because some of my files are rather large.

---

From: Watson Ladd <[email-masked]>
Date: Mon, 19 Sep 2016 11:54:26 -0700

> doc; the challenge would be socializing it to the people who need to read

The first problem is that there isn't an easy library to integrate that
will handle this. If it's a five minute fix that's very different from a
long development process. And no, adding better support to NSS doesn't
count: NSS has no documentation, as well as missing some important security
features. (NSS diffie-hellman ephemeral keys don't rotate for instance).

If you want applications to use tokens you need to make doing so a
solution, not a problem. Standards can help, but they have also massively
hurt.

>> ³
http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/tests/Makefile.am

-- 
"Man is born free, but everywhere he is in chains".
--Rousseau.

---

From: David Woodhouse <[email-masked]>
Date: Mon, 19 Sep 2016 20:28:04 +0100

On Mon, 2016-09-19 at 12:35 -0400, Phillip Hallam-Baker wrote:
> This is a very common problem and one that I encounter on an hourly
> basis as I write code for the Mesh. There are three separate formats
> used for public keys in SSH and four for private.
> 
> This is all stuff that has dropped off the table as far as the
> standards groups are concerned because 'it isn't protocol that goes
> on the wire'. Except of course it does.
> 
> The way I think we have to approach a solution is to use a container
> of some type whether that is MIME or JSON that has a slot for
> metadata describing the content type to follow:

Hm... the problem is that there exists a plethora of different file
formats, and applications are massively inconsistent about which ones
they support.

Your proposed solution is to add a new file format to the mix?

That is... not entirely what I had in mind. :)

I suppose it *would* improve consistency, in an unhelpful kind of a
way... it would give a new format that all existing applications would
*consistently* fail to support,

-- 
dwmw2

---

From: David Woodhouse <[email-masked]>
Date: Mon, 19 Sep 2016 20:56:36 +0100

On Mon, 2016-09-19 at 11:54 -0700, Watson Ladd wrote:
> The first problem is that there isn't an easy library to integrate
> that will handle this. If it's a five minute fix that's very
> different from a long development process.

I'll restate that differently: the problem is that *all* the crypto
libraries go out of their way to make it *hard* for applications to do
this correctly.

I have *pondered* splitting out my file-handling code from OpenConnect
into a BSD-licensed library. That does handle the task of working out
what type of file it's dealing with, and tickling the crypto library
(well, OpenSSL or GnuTLS) in precisely the right way to load it.

On the whole though, I'd rather just fix the libraries so that the
application doesn't *need* to do that kind of nonsense.

>  And no, adding better support to NSS doesn't count: NSS has no
> documentation, as well as missing some important security features.
> (NSS diffie-hellman ephemeral keys don't rotate for instance).

Sure, there are *lots* of things to be fixed.

Fixing NSS to use PKCS#11 URIs addresses only part of the problem.
Using *files* from NSS is also a complete pain in the posterior. There
exists nss-pem but it's baroque and supports only a tiny set of file
formats.

> solution, not a problem. Standards can help, but they have also
> massively hurt.

When you say 'tokens' you're talking about PKCS#11? That part is
actually relatively easy, at least for the crypto libraries I've been
looking at. NSS is mostly resolved; there's the question of loading the
system-configured PKCS#11 providers but we have a way forward and
patches filed for that too: https://bugzil.la/1296263

GnuTLS has worked for as long as I can remember — you just pass it a
PKCS#11 URI in place of a filename and it Just Works™. And I've fixed
up its file support in places too, for example by adding support for
the OpenSSL encrypted PEM files.

For OpenSSL there is engine_pkcs11, which I've recently fixed so it is
loaded simply with ENGINE_by_id("pkcs11") and takes PKCS#11 URIs to
load keys and certs. Longer-term, there are moves afoot to integrate
PKCS#11 support directly into OpenSSL.

Other crypto libraries exist, of course, but not so much on platforms
where PKCS#11 is prevalent.

But that's just me tilting at windmills on my own. The point of
reaching out in this forum is to try to reach a consensus on what we
should expect from applications, and maybe even get others to help :)

-- 
David Woodhouse                            Open Source Technology Centre
[email-masked]                              Intel Corporation

---

From: Michael Richardson <[email-masked]>
Date: Tue, 20 Sep 2016 10:49:31 -0400

> exists nss-pem but it's baroque and supports only a tiny set of file

NSS seems hostile to having private keys loaded. It expects to manage all of
that, and for partly good reasons: the private key may be in a module or
something.  But the result is that you basically can't write regression tests
for NSS. At least that's my experience.

    > should expect from applications, and maybe even get others to help :)

I expect applications to:
  a) be runable without a system resource.
  so:
  b) they can be tested without an install.
  so:
  c) I can run the executable from the source directory.

It's great if applications, once installed, can be told about system wide
keys and the like, and we can arrange to share things appropriately, but too
often the system-wide stuff has gotten in the way of actually making things
work.   Frankly, it's why SSH took off in the 1990s, while ssltelnet and
ktelnet failed: minimal to no infrastructure.  Building scalable systems
doesn't mean building them for 1,000,000 people, it means building them for a
range, ideally down to 1.

I think that the major problem with X.509 client certificates is that many
applications and protocols don't know if 509 is being used as a container for
a self-signed certificate, for poorly(privately) signed certificate, a
corporate CA, or a webCA.

That's where PHB's suggestion of a new meta-format would win.
(It means that we could eventually not have the keys in X.509 format.)

--
Michael Richardson <[email-masked]>, Sandelman Software Works
 -= IPv6 IoT consulting =-

---

From: Alan DeKok <[email-masked]>
Date: Tue, 20 Sep 2016 11:43:03 -0400

> (It means that we could eventually not have the keys in X.509 format.)

  This proposal may be applicable:

https://tools.ietf.org/html/draft-winter-opsec-netconfig-metadata-00

  Alan DeKok.

---

From: David Woodhouse <[email-masked]>
Date: Tue, 20 Sep 2016 16:57:46 +0100

>   c) I can run the executable from the source directory.

Yes, all of these are good practice. They are orthogonal to what I'm
trying to achieve, but certainly I wouldn't do anything to *discourage*
the above.

> ktelnet failed: minimal to no infrastructure.

I think that's orthogonal to my purpose here too. You're talking about
the infrastructure on the server side, used to determine which client
keys to trust.

What I'm talking about here is *clients* finding the keys to use.

For X.509 certificates and keys, applications need to be able to
support various file formats *and* should support using objects from a
system-specific central store *if* such exists on the platform.

Starting with just the files... take a look at the test cases in
http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/tests/Makefile.am

There are various PKCS#1, PKCS#8, PKCS#12 files in various PEM and DER
permutations with a selection of weak and strong encryption types (and
lack of encryption).

I know of NOT A SINGLE APPLICATION which will Just Work™ for every one of those test cases.

And looking beyond files: if I go and purchase a hardware crypto device like a Yubikey, and plug it into my system. I install the OpenSC package which has a PKCS#11 provider module for it, and provision a key in it.... now, how do I use it?

The answer should be simple. I determine a RFC7512 identifier for the key I want to use (e.g. 'pkcs11:manufacturer=piv_II;id=%01') and then every application in the system SHOULD just accept that identifier in place of a filename.

That is the scope of what I'm trying to do here — nothing more. Just making client applications consistent in what forms of key they accept, and how the user identifies them.

Note that I don't need to *install* my client application for the system certificate support to work. I can run it from its build directory and using "-c 'pkcs11:manufacturer=piv_II;id=%01'" should still work. My test cases jump through hoops to use a SoftHSM token for testing, with its storage database actually kept in the git repository. But that's just for testing.

-- 
dwmw2

---

From: David Woodhouse <[email-masked]>
Date: Tue, 20 Sep 2016 17:06:38 +0100

> https://tools.ietf.org/html/draft-winter-opsec-netconfig-metadata-00

That looks like a layer above what I'm talking about. My goal is that
we should be able to refer to certificates in a simple consistent way.

If the certificate is in a system store then applications should allow
it to be used by means of a consistent identifier string (which is
defined by RFC7512 for PKCS#11, and may be different for OSX/Windows
system certificate stores).

If the certificate is in a file, obviously the identifier is the
filename... but we need to fix applications so that they actually
*accept* all types of files. Which as I said, none of them do at the
moment.

Looking at the proposal above, I see there is some attempt to handle
certificate encodings — it the CertEncodingEnum has values of PEM, DER,
and P12.

This looks a lot like the problematic applications we need to fix...
for PKCS#1 and PKCS#8 you have to manually specify whether it's PEM or
DER file even though the software could work that out for itself. And
for PKCS#12 you *don't* have to specify; it's going to assume DER. All
very suboptimal.

My assertion is that applications shouldn't *need* that nonsense, and
should just take the filename and deal with the contents. Please don't
entrench that horridness further.

It also seems that the proposal you reference doesn't have any kind of
support for using keys from hardware. If the key I want to use is
identified by an RFC7512 PKCS#11 URI, how do I indicate *that* in this
format?

-- 
dwmw2

---

From: Alan DeKok <[email-masked]>
Date: Tue, 20 Sep 2016 12:36:01 -0400

> system certificate stores).

  I think that the two solutions complement each other.

> for PKCS#12 you *don't* have to specify; it's going to assume DER. All

  I agree.

> entrench that horridness further.

  I understand, but... that's easier than scanning the file to see if it's one of N possible unknown formats.  And likely more secure.

> identified by an RFC7512 PKCS#11 URI, how do I indicate *that* in this

  The proposal would need updating to handle that.

  Alan DeKok.

---

From: David Woodhouse <[email-masked]>
Date: Tue, 20 Sep 2016 18:08:42 +0100

On Tue, 2016-09-20 at 12:36 -0400, Alan DeKok wrote:
>   I understand, but... that's easier than scanning the file to see if
> it's one of N possible unknown formats.  And likely more secure.

Easier for whom? Not for the user, certainly. Users should be able to
ask applications just to use a certificate/key from a given file,
without worrying about the minutiae of what's inside it.

Besides, it's not like it's hard to tell the difference between PEM and
DER files. And if you're already accepting "DER" as a filetype, that
covers all manner of stuff including PKCS#8, PKCS#1 and the various
unencrypted forms of DSA and EC keys. It's not like recognising PKCS#12
in that code path is particularly difficult *either*, if you were doing
it properly.

Which, as I noted, no application does.

>   The proposal would need updating to handle that.

Yes. Yes, it does :)

-- 
dwmw2

---

From: Michael Richardson <[email-masked]>
Date: Tue, 20 Sep 2016 20:29:51 -0400

David Woodhouse <[email-masked]> wrote:
    > And looking beyond files: if I go and purchase a hardware crypto device
    > like a Yubikey, and plug it into my system. I install the OpenSC
    > package which has a PKCS#11 provider module for it, and provision a key
    > in it.... now, how do I use it?

    > The answer should be simple. I determine a RFC7512 identifier for the
    > key I want to use (e.g. 'pkcs11:manufacturer=piv_II;id=%01') and then
    > every application in the system SHOULD just accept that identifier in
    > place of a filename.

yes, that would be great. Maybe we need to register the pkcs11: URI, such
that we can then say it's a URI, and file:// would also naturally work.

    > That is the scope of what I'm trying to do here — nothing more. Just
    > making client applications consistent in what forms of key they accept,
    > and how the user identifies them.

+10.

    > Note that I don't need to *install* my client application for the
    > system certificate support to work. I can run it from its build
    > directory and using "-c 'pkcs11:manufacturer=piv_II;id=%01'" should
    > still work. My test cases jump through hoops to use a SoftHSM token for
    > testing, with its storage database actually kept in the git
    > repository. But that's just for testing.

+100.

---

From: Peter Gutmann <[email-masked]>
Date: Wed, 21 Sep 2016 15:11:49 +0000

David Woodhouse <[email-masked]> writes:

>permutations with a selection of weak and strong encryption types (and lack
>of encryption).
>

That's not surprising, you've barely scratched the surface of the mess of
what's out there for storing private keys, some of it completely undocumented,
and yet you want some magic piece of code or app to be able to work with all
of them.  Not just that, but you're saying that you want Internet Explorer to
be able to grab GPG keys and OpenSSL to be able to grab Apple account keys and
Flash Player to be able to grab OpenSSH keys.  Is that really what you're
after?

Peter.

---

From: David Woodhouse <[email-masked]>
Date: Wed, 21 Sep 2016 22:57:54 +0100

> Flash Player to be able to grab OpenSSH keys.  Is that really what you're

No, the scope here is limited to X.509 certificates and the associated
keys, and the *common* formats for those keys. Using GPG and OpenSSH
private keys is definitely a long way outside that scope.

So let's assume I have a key in a given PEM or DER format file as
issued through my employer's PKI infrastructure (and associated client-
side provisioning tools.

I also have a variety of client applications on my system (openconnect,
openvpn, curl, wpa_supplicant, etc.) which can use certificates from
files.

I just want those applications to work consistently. I don't want them
to support different subsets of the common file formats depending on
which crypto library they happen to be built against this week, and how
much attention their author was paying to such matters.

There are a variety of forms which have been the *default* output of
tools like OpenSSL over the years, and I've recently been finding some
of those which are not accepted by certain client applications (and
libraries). That's not acceptable. I don't want *every* possible format
to be supported; just the common ones which people are *likely* to
encounter in real life.

And for hardware tokens... if my employer provided me with a hardware
crypto token such as a Yubikey, and the OpenSC driver is installed
correctly in my system, then I *really* want to be able to pass the
RFC7512 identifier "pkcs11:manufacturer=piv_II;id=%01" to any of those
applications and expect them to Just Work™.

That's actually a very reasonable request, I think.

-- 
dwmw2

---

From: Peter Gutmann <[email-masked]>
Date: Thu, 22 Sep 2016 05:04:31 +0000

>That's actually a very reasonable request, I think.

I don't know about reasonableness (hey, possibly it is), but it's highly
unlikely it'll ever be addressed.  This situation has been with us for
twenty years without much, if any, progress being made (you can go back
two decades and find people complaining about the same thing).  You just have 
to work around it... that kinda sucks, but then lots of life in general does.

Peter.

---

From: David Woodhouse <[email-masked]>
Date: Thu, 22 Sep 2016 11:27:19 +0100

> to work around it... that kinda sucks, but then lots of life in general does.

Heh, that's a very defeatist attitude :)

I'm happy to tilt at windmills, and writing out a clear set of
guidelines for applications to follow will be an important step to
pushing them in the right direction.

Even without that, there *has* been progress on this front.

Below is a non-exhaustive list of "crappiness" that users have
experienced — especially with a focus on Linux and similar operating
systems. Note that we have *already* fixed almost all of these, so I am
not as pessimistic as you about it being "highly unlikely it'll ever be
addressed".

I think it makes a lot of sense to write up the recommended best
practice, and fix the crypto libraries so they make it hard for
applications *not* to follow the best practice, instead of making it
hard for applications to get it *right*.

Sure, it won't be a panacea, but a world where users have higher
expectations and file bugs for "this application does not follow the
documented best practice" *will* be a better place.

Here's that list of mostly-already-fixed problems:

 "My distribution builds this application against GnuTLS but this PEM 
  file is in the non-standard OpenSSL encrypted form so it doesn't 
  work."

 "My token doesn't expose the EC public key so I can't authenticate to
  the VPN... unless I rebuild OpenConnect to use GnuTLS instead of 
  OpenSSL. But I'm on CentOS where GnuTLS is too old to support Cisco's
  broken pre-standard version of DTLS."

 "My distribution builds cURL against NSS so the standard form of the
  PKCS#11 URI doesn't work and I have to use a NSS-specific way to
  specify the cert instead."

 "Hm, my token is installed correctly and works everywhere. I can see 
  my cert in 'seahorse' and 'p11tool' and use it from OpenConnect… but
  why doesn't it work in Firefox? Oh, because NSS doesn't actually 
  load the tokens listed in the system configuration."

 "OK, so I fixed that... but now why doesn't it show up in Chrome. That
  uses NSS too, right? Oh, I have to add it to a *different*
  configuration file, ffs."

 "Now openvpn doesn't support the standard URI form either, it uses
  libpkcs11-helper which has an entirely different format that I need
  to use to specify the certificate."

 "Ick, when wpa_supplicant is built against OpenSSL it needs all this 
  explicit "engine" configuration nonsense in *addition* to needing
  the cert to be specified in a non-standard form. Unlike when built
  with GnuTLS, when it does just accept a RFC7512 PKCS#11 URI in its
  'certificate' option."

 "Argh, FFS. The OpenSSL engine doesn't load the tokens listed in the 
  system configuration *either*, and needs to be explicitly told which
  provider module to load. And my application doesn't even give me the 
  hook to do that."

 "Oh, 'openvpn --cert' takes PEM files according to its documentation…
  but wait, *this* is a PEM file and it doesn't seem to work. Why?"

 "Hm, all this *used* to work but when I just renewed my certificate,
  it magically stopped working... oh, because the new cert was issued
  with OpenSSL 1.1 and that uses a SHA256 HMAC by default which this
  version of GnuTLS doesn't cope with.

 "Oh, my cert is marked with CKA_PRIVATE but libp11 doesn't return it
  from PKCS11_enumerate_certs() even *after* I log in, so the
  application can't find it."

 "Hm, I need to configure my VPN to use the cert in my token but the
  GUI configuration dialog only lets me choose from a file."

---

From: Alan DeKok <[email-masked]>
Date: Thu, 22 Sep 2016 10:18:22 -0400

> not as pessimistic as you about it being "highly unlikely it'll ever be

  I see many of those issues as:

* not implementing the standards correctly

* using application-specific solutions instead of pre-existing solutions already in wide use

* implementations which produce bad or non-existent log messages 

  In my experience, many critical network applications or "security" applications produce wonderful messages like "failed".  Or "byte 14 not 6 in my_foo_function()".  Nonsense like that degrades security.

  This problem isn't programming, it's psychology.  The programmers have a mental model in which administrators know everything the programmers know.  This mental model is wrong.  Administrators (and end users) need *different* information than what programmers typically produce.

  As a case in point, I tried to get client certs working with a commonly-used application.  I followed the docs, and everything looked like it succeeded.  Yet the application refused to use the client certificate. Why?  I have *no idea*.  There were no log messages, error messages, or *anything* which let me know what the application was doing, and how I could fix the problem.

  I eventually gave up, and installed a competing product.  Which worked fine the first time.

  I would hope that any X.509 best practice document takes this into account.  i.e. recommend that the application have a "security log" which describes WHERE it's looking for certs, WHAT it found, WHY it worked (or didn't work).  Recommending formats for log messages would be a big plus.  It would be good to walk through typical usage scenarios, and explain which log message should be produced when.  Both for "it works" cases, and for "it doesn't work" cases.

  Simple messages like that go a *long* way to educating the end user.  Instead of clicking through warning pop-ups, the user has some insight into what's going on, and why.  This empowers the end user to make better choices.

  Alan DeKok.

---

From: Ted Lemon <[email-masked]>
Date: Thu, 22 Sep 2016 11:32:18 -0400

On Thu, Sep 22, 2016 at 10:18 AM, Alan DeKok <[email-masked]>
wrote:

>  I would hope that any X.509 best practice document takes this into
> account.  i.e. recommend that the application have a "security log" which
> describes WHERE it's looking for certs, WHAT it found, WHY it worked (or
> didn't work).  Recommending formats for log messages would be a big plus.
> It would be good to walk through typical usage scenarios, and explain which
> log message should be produced when.  Both for "it works" cases, and for
> "it doesn't work" cases.
>
>   Simple messages like that go a *long* way to educating the end user.
> Instead of clicking through warning pop-ups, the user has some insight into
> what's going on, and why.  This empowers the end user to make better
> choices.
>

Yes, this!

---

From: David Woodhouse <[email-masked]>
Date: Thu, 22 Sep 2016 17:08:05 +0100

> * using application-specific solutions instead of pre-existing solutions already in wide use

And partly the fact that there are TOO MANY standards; both de facto
and de jure.

Just look at the class of "stuff which OpenSSL has produced by default
over the years for private keys", including the output of tools such as
'openssl req -new'. There's about a dozen different file formats with
which applications should "Just Work", right there.

We added HMAC-SHA256 support to GnuTLS PKCS#12 just a week or two back,
because OpenSSL 1.1 does that by default. We added pbeWithMD5AndDES-CBC 
support too, Turns out OpenSSL 1.0.2 is still producing *that* by
default with 'openssl pkcs8 -topk8' :)

>   In my experience, many critical network applications or "security"
> applications produce wonderful messages like "failed".  Or "byte 14
> not 6 in my_foo_function()".  Nonsense like that degrades security.

I'd note that those are two very different classes of bad error message.

The first is bad because it doesn't provide any information about what
went wrong; merely that something did. This is the type of bad error
message which is most common.

The second is bad because it's giving the wrong information. But it's
still better than the first, because at least I can go and read
my_foo_function() and see what's going on.

> account.  i.e. recommend that the application have a "security log"
> which describes WHERE it's looking for certs, WHAT it found, WHY it
> worked (or didn't work).  Recommending formats for log messages would
> be a big plus.  It would be good to walk through typical usage
> scenarios, and explain which log message should be produced when. 
> Both for "it works" cases, and for "it doesn't work" cases.

Crappy error handling is a personal bugbear of mine... but I'd actually
tried *not* to get too distracted by it in putting together the draft.
It's not really specific to X.509 best practices at all. Nevertheless,
some wording on it did slip into the draft that Nikos and I have
started working on, because I just couldn't help myself.

Here is a very early attempt at that draft. I have tried quite hard to
limit the scope because as this discussion has showed, there are plenty
of possibilities for "mission creep".

http://david.woodhou.se/draft-woodhouse-cert-best-practice.html
https://github.com/dwmw2/ietf-cert-best-practice

I should point out that although I put Nikos's name on it and he has
contributed many improvements, any egregious errors and stupidities in
it should be blamed on me. Especially as I didn't actually double-check 
with him before posting it here. :)

-- 
dwmw2

---

From: Ted Lemon <[email-masked]>
Date: Thu, 22 Sep 2016 14:24:10 -0400

This looks good generally.   However, one concern I have about it is that
we actually really don't want applications to have access to private keys.
  Well, anyway I don't.   I want the private key to be in an engine where
it can't be gotten out by the application, and I want the application to
provide data for the engine to process: cleartext in, ciphertext out.
This is a big ask, and I realize that, so I am not saying that this
document is wrong.   But I'm bringing it up because I wonder if you've
thought about it, and possibly considered specifying this operational model
as well.   Not being a security expert myself, is what I am asking for
technically unreasonable, or do you just think it doesn't need to be scoped
in to this work?

---

From: David Woodhouse <[email-masked]>
Date: Thu, 22 Sep 2016 20:01:05 +0100

On Thu, 2016-09-22 at 14:24 -0400, Ted Lemon wrote:
> This looks good generally.   However, one concern I have about it is
> that we actually really don't want applications to have access to
> private keys.   Well, anyway I don't.   I want the private key to be
> in an engine where it can't be gotten out by the application, and I
> want the application to provide data for the engine to process:
> cleartext in, ciphertext out. 

This sounds a little bit like the model we were using with TPM(v1).
With the OpenSSL TPM ENGINE, the user 'wraps' a key with the TPM and
gets to keep a PEM file that starts like this:

-----BEGIN TSS KEY BLOB-----

Whenever the user wants to use that key, they simply use that PEM file
instead of one of the other multitude of supported formats and it "Just
Works". I had lots of fun making that work for GnuTLS too:
http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/gnutls_tpm.c

Is that what you were after? I did consider writing that one down too,
but figured it was a little too esoteric. And perhaps we should have
exposed the TPM via a PKCS#11 provider in the first place anyway.

> document is wrong.   But I'm bringing it up because I wonder if
> you've thought about it, and possibly considered specifying this
> operational model as well.   Not being a security expert myself, is
> what I am asking for technically unreasonable, or do you just think
> it doesn't need to be scoped in to this work?

I absolutely agree that applications MUST NOT rely on having access to
the actual private key material. They need to support using opaque keys
from hardware and software tokens. But I was envisaging that PKCS#11
would be the vehicle for that.

---

From: Ted Lemon <[email-masked]>
Date: Thu, 22 Sep 2016 15:26:10 -0400

Well, here is the reason that I carefully said "not a security expert"
earlier.   I suspect that PKCS#11 is a better answer than a shim.   Thanks
for the clue stick!

---

From: David Woodhouse <[email-masked]>
Date: Thu, 22 Sep 2016 20:46:56 +0100

On Thu, 2016-09-22 at 15:26 -0400, Ted Lemon wrote:
> Well, here is the reason that I carefully said "not a security
> expert" earlier.   I suspect that PKCS#11 is a better answer than a
> shim.   Thanks for the clue stick!

FWIW if you want to put the key beyond copying by normal users, for
many purposes you can do that right now on a Linux system. See
https://bugzilla.gnome.org/show_bug.cgi?id=704866#c9 (and #c10)

The example there is the OpenConnect VPN client, but on Fedora if you
find *any* application which would accept a certificate in a file and
doesn't accept a RFC7512 PKCS#11 URI, please file a bug and Cc me.
Because although I'm only now working on this I-D, that much *is*
already part of the Fedora packaging guidelines.

And if you're not on Linux or something similar... and if you're not on
Windows or OSX which have their own keystores which at least *pretend*
to prevent the kind of export you're talking about, then what platform
*are* you thinking of? :)

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Sun, 25 Sep 2016 18:48:59 -0700

> On Sep 20, 2016, at 9:06 AM, David Woodhouse <[email-masked]> wrote:
> 
> My goal is that

Hello David:

draft-seantek-certspec “Textual Specification for Certificates” is exactly what you’re looking for.

https://tools.ietf.org/html/draft-seantek-certspec-09

That is for certificates. And yes, it handles pkcs11 just like everything else. It also has an algorithm for automatically detecting textual encoding (RFC 7468) vs. DER encoding. Discussions about PKCS #12 issues were added to recent drafts.

***

Private keys are another matter. The approach could easily be extended to handle private keys. They are just identifiers, after all. However, by definition secure private keys are a “local matter”. I do not see the value of standardizing an identifier for private keying materials when the implementations are all different and are not supposed to communicate with each other. You can, of course, always refer to a private key indirectly, by referencing an associated certificate. It is very plausible to identify a certificate stored in a local file (that does not need to be encrypted), and then to look up the associated private key on a token that has a lot more protection around the key, by using the certificate or its metadata as the dbkey/index.

[The aforementioned paragraph is also responsive to Ted Lemon’s concern: “one concern I have about it is that we actually really don't want applications to have access to private keys.”]

Regards,

Sean

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 10:17:27 +0100

> https://tools.ietf.org/html/draft-seantek-certspec-09

Thanks; that's very interesting. I'm not sure it covers exactly the
same use case, but it's very closely related.

> That is for certificates. And yes, it handles pkcs11 just like
> everything else. 

... but not like RFC7512 does, I note. Is it worth trying to achieve
some better consistency there? After all, I can *already* refer to the
certificate in my crypto token consistently as 

	'pkcs11:manufacturer=piv_II;id=%01'

in a variety of applications using different crypto libraries. And in
fact on my operating system of choice I can file a bug for any
application which *doesn't* accept that string, when it would have
taken a filename. So I'd definitely like to see your draft make
explicit reference to RFC7512 in some form or other.

> ***
> 
> Private keys are another matter. The approach could easily be
> extended to handle private keys. They are just identifiers, after
> all. However, by definition secure private keys are a “local matter”.
> I do not see the value of standardizing an identifier for private
> keying materials when the implementations are all different and are
> not supposed to communicate with each other. 

Ah, but that is *precisely* the matter I was most concerned about. It's
not so much about implementations communicating with each other; it's
about consistency and (hence) usability.

Not very long ago, in order to use that key in the crypto token I
mentioned above, I had to do something *different* for fairly much
every application:

 • for OpenVPN, I had to manually specifier the PKCS#11 provider
   module and use one form of identifier string.
 • for OpenConnect, RFC7512 identifiers Just Worked, and it used
   the PKCS#11 providers indicated by the system configuration. (Yay!)
 • for Curl (if built with NSS) I needed to manually edit configuration
   files to make it load the right module, and then refer to the
   object by a *third* form of identifier string.
 • for wpa_supplicant I had to manually configure it to use an OpenSSL
   "Engine", specify the provider in yet *another* different manner
   because that also ignored the system configuration, and then give
   the certificate ID in a *fourth* different form.

And that was just for the applications which *could* use PKCS#11. Many
just couldn't do it at all. And for some, they needed to be configured
differently depending on which crypto library they'd been built
against.

It made me kind of sad. FWIW I have all of the above just taking
PKCS#11 URIs according to RFC7512 now, without any of the additional
configuration nonsense like loading engines and specifying provider
modules.

Now, *part* of that is addressed by your draft (although it's already
addressed by RFC7512 in the case of PKCS#11, and the conflicts there
want resolving). But other parts are not — and I'm not sure you really
want to expand your scope to cover them. They include:

 • Using the system configuration for which PKCS#11 providers to load.
 • The search algorithm, identifying when to log in to a token to
   attempt to find a certificate with CKA_PRIVATE and how to locate
   the key corresponding to a given certificate, etc.
 • The requirement that opaque private keys without access to the
   corresponding public key SHALL work.

That's just for PKCS#11. of course. For files there are a different set
of issues — mostly the fact that every application on the system will
currently support a *different* subset of private key file formats. So
a user with a certificate+key provisioned through her organisation's
proprietary scripting will find that it works with *some* applications
and not others, for reasons which are entirely intractable, such as:

 • It uses the non-standard OpenSSL 'encrypted PEM' format.
 • It uses a SHA256 HMAC which isn't universally supported.
 • It is encrypted with DES-MD5, which isn't universally supported.
 • It is in DER form, which applications need to jump through hoops
   to cope with loading because crypto libraries hate us all.

The idea of my draft is to give a set of "best practice" guidelines for
applications so that the user *can* just use the same certificate and
key with any well-behaved application, with exactly the same
identifier, and it will Just Work.

It's not *just* about the identifier though, and in fact I've mostly
tried to make it *not* about the identifier. I just defer to RFC7512
and obviously to filenames. For the system certificate stores I just
say that if a convention exists, it should be supported — and it sounds
like your draft would be the ideal solution to fill that gap.

So while there is certainly an overlap with your draft, there's also a
lot to cope with that *isn't* already the primary target of your draft.

If you want, I'm happy to work with you to *make* your draft cover
this. But I suspect there would be sufficient conflict in our use cases
that it's best just to ensure that they complement each other to
achieve their respective goals. What do you think?

For reference, the current version of my nascent draft is at
http://david.woodhou.se/draft-woodhouse-cert-best-practice.html and
it's also at https://github.com/dwmw2/ietf-cert-best-practice

> You can, of course, always refer to a private key indirectly, by
> referencing an associated certificate. It is very plausible to
> identify a certificate stored in a local file (that does not need to
> be encrypted), and then to look up the associated private key on a
> token that has a lot more protection around the key, by using the
> certificate or its metadata as the dbkey/index.

Yes, there is lots of fun to be had here. Lots of reasonable heuristics
for how to find a key given the certificates — and thus lots of scope
for applications to be inconsistent and for users to complain "it works
in XXX, so why doesn't exactly the same cert work in YYY?".

I've attempted to address this with the search algorithm for PKCS#11.
For files there's not a lot you can do although I do mention that if
the cert has extension '.crt' and doesn't actually contain the private
key, you might look for a corresponding file with extension 'key'.

There are probably more improvements that can be made in this area,
especially when it comes to the system stores on Windows and OSX.

> [The aforementioned paragraph is also responsive to Ted Lemon’s
> concern: “one concern I have about it is that we actually really
> don't want applications to have access to private keys.”]

Yes, we absolutely need to support and encourage that use case. That is
part of my motivation for pushing to have PKCS#11 supported
consistently across applications on platforms where that's the best
answer.

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 12:10:41 -0700

> same use case, but it's very closely related.

Great!

> explicit reference to RFC7512 in some form or other.

I can do that...although the value of doing so may be a bit lost on me. 
The general syntax would be:

URI:pkcs11:manufacturer=piv_II;id=%01

The syntax of "URI:uri" (with URI: prepended) has a long and tumultuous 
history. You can look at the draft history to see why.

Applications for draft-seantek-certspec are hunting for certificates on 
the order of sub-milliseconds: looking up a certificate could be done in 
a blocking operation. This would be the case, for example, when a TLS 
server (web server, IMAP server, etc.) or client boots up and needs the 
certificate before starting its first TLS connection. As a general 
matter, URIs strongly imply network access; therefore they are not as 
important as the other types of specs.

Any application that plans on using a certificate with its corresponding 
private key should obviously have the certificate on-hand and 
at-the-ready. Even if the private key is unavailable (e.g., the hardware 
token is not in the slot), some pointer that shows that a private key is 
known to be around, has to be immediately available. That way the UI can 
prompt the user for the right device.

A distinguishing feature of URIs is that it is limited in its repertoire 
of characters to a strict subset of ASCII, with % percent-encoding. This 
means that LDAP strings are going to look very convoluted, with a lot of 
%20, %2F, %3B, etc. throughout. If you want to permit users to specify 
strings without double or triple % encoding and \ escaping and whatnot, 
then I can buy an argument to promote "p11:" or similar to the top of a 
certspec, and not buried into the "URI:" spec type. There is precedent 
for this because there are already BASE64 and HEX specs, which duplicate 
URI:data: in functionality, but are demonstrably easier to use.

By the way, RFC 7512 contains a serious bug: the | character is not 
valid in URI [RFC3986]. I don't know how that character snuck through 
the RFC process, but it's not a valid URI.

RFC 7512 contains a second, less serious bug: "The URI scheme does not 
use the fragment component." Well that may or may not be good advice. I 
don't see why a PKCS #11 token can't return a blob that is plain text 
(text/plain), in which case, fragment would be defined by RFC 5147. 
Furthermore, PKCS #11 is actually Internet media type-aware: see 
CKA_MIME_TYPES, for example, in that standard.

> configuration nonsense like loading engines and specifying provider

That is indeed a list of horribles.

But for applications that are PKCS #11 based, one could easily write a 
script that takes a pkcs11: URI as input and outputs the right flips, 
switches, config files, and API calls to do what the pkcs11: URI is 
saying to do. Probably would take less than a day.

For applications that are *not* PKCS #11 based (macOS Keychain Services, 
Windows CNG), using a PKCS #11 URI would be..."grotesque". I don't know 
of a better way to put it.

> lot to cope with that *isn't* already the primary target of your draft.

Okay. Yes, the primary target of the draft is identifying certificates 
(uniquely and unambiguously), and providing associated attributes with 
the certspec. Interestingly, one of those "associated attributes" could 
very well be: "hint or directive about where to find the private key". 
So that is a point of extension that we could collaborate on, whether in 
draft-seantek-certspec or in a related draft.

For interoperable private key formats, I favor PKCS #8 PrivateKeyInfo 
(as .p8) and PKCS #8 EncryptedPrivateKeyInfo (as .p8e). They are 
standardized, widely-supported, and algorithm-agile. They are also 
simple enough that even if a crypto stack doesn't support them directly, 
"adapters" can be built that shoehorn the data into other container 
formats, such as PKCS #12, OpenSSL's proprietary formats, and so on. 
(Note that I worked on the registrations for both application/pkcs12 and 
application/pkcs8-encrypted.)

> achieve their respective goals. What do you think?

I am happy to make draft-seantek-certspec more useful to different 
constituents!

The focus needs to remain on uniquely identifying cryptographic data 
items, rather than as a generalized querying format. (Discussed in 
draft.) However, I like the idea of a standardized attribute that points 
to the location of a private key. Such an attribute could also be 
conveniently serialized into other formats, e.g., as attributes in PKCS 
#11 and PKCS #12, and as Certificate Properties in Microsoft CryptoAPI. 
That is exactly how crypto stacks operate anyway: they tag a certificate 
with a little pointer that points to where to find the private key, if 
one exists.

> it's also at https://github.com/dwmw2/ietf-cert-best-practice

Thanks, I read it.

> especially when it comes to the system stores on Windows and OSX.

Okay.

> consistently across applications on platforms where that's the best

Good.

Regards,

Sean

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 20:48:46 +0100

> important as the other types of specs.

As far as I can tell, the PKCS#11 URI is not a URI. It's just a set of
search terms, similar in many ways to the ones in your own draft —
except with a specific focus on what's searchable in the PKCS#11 API.

It's just an identifier; it's not valid to make general inferences
about it, along the lines of "URIs strongly imply network access".

As such, I'd be inclined to suggest that the general syntax for it in
your draft might be the PKCS#11 URI itself, starting with 'pkcs11:'.

> %20, %2F, %3B, etc. throughout. 

Who said anything about LDAP strings? I was *only* talking about the
PKCS#11 identifiers as defined in RFC7512. Which aren't really URIs
although that term is used there quite a lot :)

> If you want to permit users to specify 
> certspec, and not buried into the "URI:" spec type. 

No, I absolutely don't want *more* ways of referring to the same
objects, and more things for the users to try, and discover are
inconsistently supported across the set of applcatiions they use.

> the RFC process, but it's not a valid URI.

Fine, there are almost no circumstances when you might want to use the
RFC7512 identifier as if it's *really* a URI. It looks like you
*suggested* it above, but I think you're the first, and I just told you
not to :)

> CKA_MIME_TYPES, for example, in that standard.

It's an identifier for an object. It is (deliberately AFAICT) not
actually a real URI that you might for example put into the location
bar of your web browser and expect it to do anything useful.

> saying to do. Probably would take less than a day.

You could do that. Not sure it would entirely meet my criteria for
usability though. Better to fix the applications so that they all just
accept the objects in the same form, than to have different 'wrappers'
and 'config generators' for each application to work around their
differences and convert keys between formats.

> of a better way to put it.

Yes. Don't attempt to use a PKCS#11 identifier for something that's not
PKCS#11; that would be strange.

Having said that... ∃ PKCS#11 modules which expose the functionality of
the keychain and of CAPI/CNG:
     https://github.com/slushpupie/KeychainToken
     https://github.com/risacher/p11-capi
.. and then I suppose you *do* end up referencing objects therein via
PKCS#11 attributes :)

> draft-seantek-certspec or in a related draft.

Yes, that definitely warrants a further look.

> standardized, widely-supported, and algorithm-agile. 

They are also non-portable, because even when RFC5958 was published in
2010, FFS, it didn't mandate the conversion of the password to UTF-8
(let alone any mention of Unicode normalisation) for the purpose of the
key derivation.

PKCS#12 at least gets *part* of that right, by mandating UTF16BE (BMP).

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 12:55:45 -0700

> PKCS#12 at least gets *part* of that right, by mandating UTF16BE (BMP).

draft-seantek-pkcs8-encrypted-01

Glad to see someone else cares about password mapping.

:)

Sean

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 21:25:58 +0100

> draft-seantek-pkcs8-encrypted-01

OK... so now we have can say

Content-Type: application/pkcs8-encrypted; password-mapping=UTF-8

(Did you intend '*pkcs12' to mean UTF16-BE which is BMP, not UTF-16LE?)

But I've *never* seen an application make use of certs/files from any
container where that Content-Type: header might be present. It's not
even permitted to put it in PEM files, is it? So does this really buy
me anything in practice? 

And it still doesn't cover Unicode normalisation. :)

> Glad to see someone else cares about password mapping.

Mostly when it breaks :)

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 14:01:36 -0700

> (Did you intend '*pkcs12' to mean UTF16-BE which is BMP, not UTF-16LE?)
Yes, I meant UTF-16BE. That was a typo.

By the way, I've actually done quite a lot of tests on several crypto 
stacks, and none of them enforce that the Unicode code point has to be 
in the BMP. You can use surrogate pairs (which are in the BMP anyway) 
just fine.

> even permitted to put it in PEM files, is it? So does this really buy

As with any "new thing", people have to write code for the "new thing" 
to use the "new thing". If you build it, they will come...

The alternative would be to shoehorn the password mapping into some 
attribute in ASN.1. But there's no practical place for that in PKCS #8 
EncryptedPrivateKeyInfo, which is just:

EncryptedPrivateKeyInfo ::= SEQUENCE {
     encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
     encryptedData EncryptedData
}

I mean, you *could* put it in the PBKDF2-params, with a new algorithm 
identifier. But that will require writing new code to deal with the "new 
thing". No way around it, sorry.

> And it still doesn't cover Unicode normalisation. :)

Actually it does. PRECIS says NFC for password/OpaqueString. See Section 
6.2 of RFC 7613.

There were much earlier draft registrations (see the media-types mailing 
list, it's been kicking around for many months now; see also PRECIS 
mailing list) that went into some detail about NFC and stuff like that. 
The rough consensus was that it's best to let PRECIS handle that stuff: 
doing it in the security space (aka PKCS #8 or similar container) is not 
where the expertise lies.

The other point is that there is only one party that cares about the 
encoding: "you". You = the private key holder. Private keys aren't meant 
to be shared. Frankly, who cares what the octets are, as long as you can 
input the same ones into the decryption process. If you are creating the 
private key and using it on the same computing device, the encoding 
doesn't actually matter. You could record mouse clicks or voice samples 
or raw key scan codes from the kernel, and it wouldn't affect the result.

Annex M.4 of IEEE 802.11-2012 has similar insights (which is why I cited 
it).

Adding the encoding parameter actually facilitates attacks, because it 
tells an eavesdropper what bit patterns will *not* appear. Well-formed 
UTF-8 can never have octets C0, C1, or F5-FF, for example; well-formed 
UTF-8 will also bias the input to make certain bit patterns far more 
likely than others. (The KDF is designed to mitigate against biased 
input anyway, though.) The encoding parameter can also thwart attacks, 
by intentionally mislabeling the encoding. It's not cryptographically 
protected so it is subject to undetectable tampering.

Best regards,

Sean

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 22:15:34 +0100

On Mon, 2016-09-26 at 14:01 -0700, Sean Leonard wrote:
> As with any "new thing", people have to write code for the "new
> thing" to use the "new thing". If you build it, they will come...

Sure, But with this you might as well say "write it on a Post-it note
and stick it to the monitor". Because that MIME header doesn't actually
live anywhere near the key when it's stored.

If I *wanted* to fix my OpenConnect VPN client to support this, for
example, how would I go about doing so? If I've got a PKCS#8 DER
file... where do I look for this header? If I have a PEM file, do I
look for it after the '-----BEGIN ENCRYPTED PRIVATE KEY-----' line? 

> attribute in ASN.1. But there's no practical place for that in PKCS
> #8 EncryptedPrivateKeyInfo, which is just:
> 
> identifier. But that will require writing new code to deal with the
> "new thing". No way around it, sorry.

Agreed. Or just observe that actually, PKCS#5 got it right all along:
Use ASCII or UTF-8. Which are actually the same thing, since one is a
superset of the other: use UTF-8.

> encoding: "you". You = the private key holder. Private keys aren't
> meant to be shared. Frankly, who cares what the octets are, as long
> as you can input the same ones into the decryption process. If you
> are creating the private key and using it on the same computing
> device, the encoding doesn't actually matter. You could record mouse
> clicks or voice samples or raw key scan codes from the kernel, and it
> wouldn't affect the result.

Generally true, and that's the only reason why things even work as well
as they do. Also why my draft can get away with saying you should *try*
the locale charset, and also try UTF-8, etc.

But it's not *universally* true. Users operate with different locales.
Sometimes a user provisions a certificate for e.g. 802.1x
authentication, then installs it in a location where the *system* can
use it... and suddenly the locale might be different when the key is
being used. And people *do* move files between machines, perhaps as
backups or perhaps on upgrading hardware. And *sometimes* the user's
locale in the two environments might be different.

On the whole though, I'm mostly content to say that anyone who isn't
using UTF-8 consistently, this far into the 21st century, deserves
everything they get. Especially if they try using non-ASCII in their
passwords :)

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 14:20:10 -0700

> except with a specific focus on what's searchable in the PKCS#11 API.

This is surprising, because RFC 7512 Section 4.1. registers it as a 
permanent URI scheme in the Permanent URI Schemes Registry. =:-O

I thought that the whole point of a document called "The PKCS #11 URI 
Scheme" would be to make PKCS #11 items accessible in URI protocol 
slots, and conversely, to make URI protocol slots useful to PKCS 
#11-consuming applications (in addition to other URI items such as http: 
, ldap: , data: , etc.).

> your draft might be the PKCS#11 URI itself, starting with 'pkcs11:'.

URIs are meant for Internet-accessing things. The specific URI scheme 
itself may not actually do any network access, such as data: or file:. 
(Or for that matter, http://localhost/ .) But a robust 
"URI-dereferencer" is going to have to have Internet access to be of 
much use. In contrast, a file path API does not have to have Internet 
access per-se to be of use to a broad class of applications.

> although that term is used there quite a lot :)

Maybe because they are trying to be URIs. :)

LDAP Strings are used by ISSUERSN: in draft-seantek-certspec to identify 
a certificate. It's natural, readable, and widely supported.

Notably, PKCS #11 also uses distinguished names, e.g., in CKA_SUBJECT. 
But that is a digression so we need not go there too much.

> *suggested* it above, but I think you're the first, and I just told you

I think RFC 7512 itself suggests it :)

> bar of your web browser and expect it to do anything useful.

A general-purpose URI dereferencer should be able to work just fine with 
pkcs11: the same way it works with any other URI.

> differences and convert keys between formats.

OK.

I believe, in some circles, it is called "vendor lock-in".

Budget, please. :)

> .. and then I suppose you *do* end up referencing objects therein via

ok
> Yes, that definitely warrants a further look.

Great! Let's take a look at that angle.

Sean

---

From: Watson Ladd <[email-masked]>
Date: Mon, 26 Sep 2016 14:30:51 -0700

> On 9/26/2016 12:48 PM, David Woodhouse wrote:
<chop>
> encoding: "you". You = the private key holder. Private keys aren't meant to
> be shared. Frankly, who cares what the octets are, as long as you can input
> the same ones into the decryption process. If you are creating the private
> key and using it on the same computing device, the encoding doesn't actually
> matter. You could record mouse clicks or voice samples or raw key scan codes
> from the kernel, and it wouldn't affect the result.

Explain to me how you make a certificate and install it in your
favorite web server without sharing the private key between two
different programs. For extra points try changing mail clients both
with S/MIME set up, and assume you want to read all your own emails
without moving keys. That's the problem we are trying to solve.

Sincerely,
Watson Ladd

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 22:32:02 +0100

> #11-consuming applications (in addition to other URI items such as http: 

Perhaps that was the intent; we would have to ask its authors. I cannot
tell. But it doesn't seem stunningly useful in that form to me.,

> pkcs11: the same way it works with any other URI.

Yes, but I thought you just raised a bunch of reasons why you *didn't*
want to have generic URI support :)

-- 
dwmw2

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 14:55:11 -0700

> without moving keys. That's the problem we are trying to solve.

I am not entirely sure what you're trying to get at...

Having just refreshed my web server's certificate and private key 
today...first of all, I don't "make a certificate". I generated a 
private key, and created a Certificate Signing Request. Then I uploaded 
the CSR to a commercial CA. Then I downloaded the certificate that the 
*CA* made for me.

Then I copied-and-pasted the certificate into a web form for my web 
server's control panel. I also copied-and-pasted the private key into 
the same web form. The private key was not password protected, so it has 
nothing to do with PKCS #8 EncryptedPrivateKeyInfo. There is no point in 
password-protecting the private key, because the web service (taken a 
whole) needs to see the private key anyway, and the connection to the 
web-based control panel was protected with TLS.

With S/MIME, I just use PKCS #12 like everyone else. And that workflow 
specifies the password mapping as UTF-16BE with NULL. :)

When I use cryptographic tokens such as smart cards, the private key 
never leaves the token. So, there is no password: it's irrelevant. 
Sometimes the token is configured with a PIN, but the PIN is not the 
subject of this PKCS #8 EncryptedPrivateKeyInfo discussion.

Sincerely,

Sean

---

From: Sean Leonard <[email-masked]>
Date: Mon, 26 Sep 2016 14:56:13 -0700

> want to have generic URI support :)

In certspec, identifying a certificate by URI is sensible for a broad 
range of applications. Identifying a certificate by file path is also 
sensible for a broad range of applications. But it's not the only way. 
And URI (and file path) require formatting all strings in particular 
ways, which may not actually be sensible. The draft discusses 
cut-and-paste-ability.

If someone implements certspec URI specs, the easiest way to deal with 
it is to pass the URI to the system's general-purpose URI-dereferencing 
API so it "does the right thing and gives back a blob of bytes (possibly 
with media type information)".

Sean

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 23:36:45 +0100

> with media type information)".

Except that there is no "blob of bytes" that can be returned for a
private key in a PKCS#11 token.

For certificates, sure. But not keys.

-- 
dwmw2

---

From: David Woodhouse <[email-masked]>
Date: Mon, 26 Sep 2016 23:43:41 +0100

> specifies the password mapping as UTF-16BE with NULL. :)

Right. PKCS#12 is preferable to PKCS#8 in this regard. (And thanks,
OpenSSL, for screwing that up for us.¹)

> subject of this PKCS #8 EncryptedPrivateKeyInfo discussion.

Well... looking a bit further back in the thread (or indeed at
$SUBJECT), this was about application best practice. And I probably
*do* need to look at what to do with non-ASCII PINs and C_Login().

And again, I think the recommendation there needs to be the same as
PKCs#8: By all means *try* the local character set of the current
system, but make sure you also try UTF-8. I'll update my draft.

And perhaps I should make it abundantly clear that anyone who sets a
PIN in a legacy 8-bit character set, just like anyone who sets a PKCS#8
password in a legacy 8-bit character set, had better expect it to break
if they ever fall through a timewarp into the 21st century. Or travel a
few hundred miles.

You're right that it's a different problem, but it's actually *really*
similar.

-- 
dwmw2

¹ And yes, that time I *am* complaining, Viktor :)

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Tue, 27 Sep 2016 10:15:56 +0200

> tell. But it doesn't seem stunningly useful in that form to me.,

I am not one of the authors, but I participated in the drafting of
that document. The intent was to provide a consistent way for
applications to access objects stored in PKCS#11 tokens. A URI (a
string of characters identifying a resource) seemed the appropriate
way to do it.

>>URIs are meant for Internet-accessing things

Not the PKCS#11 URI.

regards,
Nikos

---

From: "Olle E. Johansson" <[email-masked]>
Date: Tue, 27 Sep 2016 12:52:23 +0200

> On 27 Sep 2016, at 10:15, Nikos Mavrogiannopoulos <[email-masked]> wrote:
> 

RFC 3986 states: 
"A Uniform Resource Identifier (URI) is a compact sequence of
   characters that identifies an abstract or physical resource.”

In definition of a “resource” it clearly says:
" A resource is not necessarily
      accessible via the Internet; e.g., human beings, corporations, and
      bound books in a library can also be resources.  Likewise,
      abstract concepts can be resources, such as the operators and
      operands of a mathematical equation, the types of a relationship
      (e.g., "parent" or "employee"), or numeric values (e.g., zero,
      one, and infinity).”

/O