Subject: [jose] PKCS#11 Support for JWKs

From: Nathaniel McCallum <[email-masked]>
Date: Wed, 28 Jun 2017 08:41:19 -0400

Has there been any interest in standardizing this?

The Jose project[0] has some initial working code (not yet published).
We are using the (new, standardized) "p11" attribute in JWKs to
replace the absence of private key material. The value of this
attribute is the URI to the key as defined by p11-kit[1].

Thus, when a JWK which lacks private key material but contains "p11"
is used for a decryption or signing process, we forward this request
to the PKCS#11 module.

Does anyone have interest in working with me on a standard for this
(or something similar)?

Nathaniel

[0]: https://github.com/latchset/jose
[1]: https://github.com/p11-glue/p11-kit

---

From: Jim Schaad <[email-masked]>
Date: Wed, 28 Jun 2017 11:22:51 -0700

I am not aware of any work being done for that purpose.  I am not sure why
you would use a JWK rather than a URI, but I can see some possibilities.

Jim

-----Original Message-----
From: jose [mailto:[email-masked]] On Behalf Of Nathaniel McCallum
Sent: Wednesday, June 28, 2017 5:41 AM
To: [email-masked]
Subject: [jose] PKCS#11 Support for JWKs

The Jose project[0] has some initial working code (not yet published).
We are using the (new, standardized) "p11" attribute in JWKs to replace the
absence of private key material. The value of this attribute is the URI to
the key as defined by p11-kit[1].

Thus, when a JWK which lacks private key material but contains "p11"
is used for a decryption or signing process, we forward this request to the
PKCS#11 module.

Does anyone have interest in working with me on a standard for this (or
something similar)?

Nathaniel

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

---

From: Nathaniel McCallum <[email-masked]>
Date: Wed, 28 Jun 2017 16:23:42 -0400

We're using a JWK with a "p11" property because the public key
material is still usable without the private key. For example,
verification of signatures or encrypting data. So, for example:

    $ jose jwk gen -o test.jwk -i '{"p11":"pkcs11:..."}'
    $ cat test.jwk
    {"crv":"P-256","kty":"EC","p11":"pkcs11:...","x":"...","y":"..."}

This JWK can be passed directly to most JOSE implementations and be
successfully used for encryption or verification and the "p11"
property will be ignored (or it can be stripped before sharing the
key). For implementations that support PKCS#11, they can detect the
absence of a private key during signing or decryption and fall back to
evaluating the "p11" property.

That is to say, PKCS#11 is not a replacement for a JWK but for the
missing private (or symmetric) key.

---

From: Vladimir Dzhuvinov <[email-masked]>
Date: Wed, 28 Jun 2017 22:46:53 +0200

Hi Nathaniel,

So what you wish to propose is a new "p11" parameter which is a PKCS#11
URI (RFC 7512)?

Vladimir

On 28/06/17 22:23, Nathaniel McCallum wrote:z

---

From: Nathaniel McCallum <[email-masked]>
Date: Wed, 28 Jun 2017 17:00:48 -0400

Correct. This parameter can be consulted for private key operations
when the private key material is unavailable.

---

From: Vladimir Dzhuvinov <[email-masked]>
Date: Fri, 30 Jun 2017 20:30:38 +0200

I was unaware of this spec until you mentioned it here. I had a look at
it last night. Am I correct that the pkcs11 URIs are simply a
representation of the config parameters used for loading Cryptoki libs
and modules?

I'm unsure how much of a utility a p11 parameter can have. The p11 URIs
seem to contain a lot of details that are not about the key, but about
drivers, hardware, the OS. Also, parameters that can change, e.g. the
HSM slots. We have a machine with two HSMs, and after a reboot the HSMs
can get a different slot assigned, which can be nuisance.

When we used JWK sets backed by Cryptoki before we took the following
approach (in Java):

 1. Load PKCS#11 KeyStore.
 2. Export the found PKCS#11 keys into a JWK set, where the key alias
    becomes the JWK "kid", the certificate is included as an option;
    each JWK keeps a reference to the private key in the store.
 3. If the private key is needed, that same reference is used to get at it.

---

From: Nathaniel McCallum <[email-masked]>
Date: Fri, 30 Jun 2017 16:17:07 -0400

On Fri, Jun 30, 2017 at 2:30 PM, Vladimir Dzhuvinov
<[email-masked]> wrote:
> I was unaware of this spec until you mentioned it here. I had a look at it
> last night. Am I correct that the pkcs11 URIs are simply a representation of
> the config parameters used for loading Cryptoki libs and modules?
>
> I'm unsure how much of a utility a p11 parameter can have. The p11 URIs seem
> to contain a lot of details that are not about the key, but about drivers,
> hardware, the OS. Also, parameters that can change, e.g. the HSM slots. We
> have a machine with two HSMs, and after a reboot the HSMs can get a
> different slot assigned, which can be nuisance.

This doesn't really describe PKCS#11 URIs; or at least how they are
used in practice. The URI standard itself is basically just a 1-to-1
mapping of all possible metadata you can extract from PKCS #11. In
that sense the standard is deficient in that it lets you generate URIs
that can only work in certain contexts.

However, in practice, implementations only use a reliable subset of
properties*. So, for example, if you use p11tool -O, you do not
receive slot identifiers (which, as you said, might change) in the
generated URIs.  The resulting URIs will work on all OSes and HW
configurations (so long as the same crypto hardware is used). Features
like driver specification are relegated to the query string within the
standard itself and are typically omitted in real world practice.

It would be entirely possible (and, in fact, the default behavior of
GNU TLS) for you to provide a URI that would match your HSM keys every
time, reproducibly. This could be easily summed up in a new JWK
standard which would recommend to avoid attributes that would make it
difficult to match. (Again, this is not hard and is widely done
already.)

Yes, we could write a new standard URI that wouldn't have these
caveats. But it would be much better to simply handles these cases
within a "recommendations" section of a new JWK standard for the "p11"
attribute.

> Load PKCS#11 KeyStore.
> Export the found PKCS#11 keys into a JWK set, where the key alias becomes
> the JWK "kid", the certificate is included as an option; each JWK keeps a
> reference to the private key in the store.
> If the private key is needed, that same reference is used to get at it.

This is precisely what we don't want to do: build custom code every
time we want to access crypto hardware. Instead, we want the José[0]
project to have exactly the same interface whether crypto hardware is
used or the private key is in the JWK directly. For example:

    $ jose jwe dec -i my.jwe -O plain.txt -k mykey.jwk
    $ jose jwe dec -i my.jwe -O plain.txt -k myhwkey.jwk

In the above case, it doesn't matter whether the private key material
is in the JWK directly or only referenced to by the JWK. We would
provide exactly the same interface from the C API as well.

This is going to be made all the more crucial for us given our (Red
Hat's) broader adoption of PKCS #11 as a system level interface. That
is, PKCS #11 is going to be much more common, not less. GNOME already
exports PKCS #11 interfaces for its keyring. GNU TLS and OpenSC's PKCS
#11 Engine for OpenSSL do too. This will be extended to the system
level as well (we have active internal projects ongoing). We are even
exploring a TPM interface via PKCS #11. All of these are using the
URIs.

We want JOSE to be a first class citizen in this world. And that
should not involve writing special-case hardware code. It should be a
matter of generating a properly formatted, standardized JWK.

* - For example, GNU TLS outputs the following parameters as the full
path to an object: model, manufacturer, serial, token, id, object and
type. These uniquely identify a PKCS #11 key object in any context.