ruby-openssl + provider interface: generating keys with provider
Michael Richardson <mcr-SWp7JaYWvAQV+D8aMU/[email protected]> Tue, 12 Aug 2025 21:15:08 -0400
| Newsgroups | gmane.comp.encryption.openssl.user |
|---|---|
| Message-ID | <[email protected]> |
I want to access providers from ruby (and ultimately, rails)
(I care about using an IDevID provisioned into a TPM2 device to sign
certain artifacts/claims. The details are not that important, unicast if you
like)
I expect the private key to remain in the TPM, rather than be loaded
from an encrypted storage, but that could change in the future.
ruby-openssl now works with openssl3, although I have CMS patches I am trying
to upstream. I've been looking at how it loads private keys.
Neither ruby-openssl, nor I think many of the openssl "apps" actually have
been updated to use the openssl 3.x OSSL_STORE*, so they are not actually
able to create or use EVP_PKEY whose keys never leave a secure element.
ruby-openssl now has an OpenSSL::Provider interface, and it can load the
tpm2-openssl provider. But that's about all.
I added an OpenSSL::PKEY.load_from_handle function that calls
OSSL_STORE_open, OSSL_STORE_load, and OSSL_STORE_INFO_get1_PKEY(store).
It seems to work. It would be nice if the man page for OSSL_STORE_open had
more information on ui_method, and post_process.
I concluded I didn't need them, and set them to NULL.
I also found code at:
https://github.com/latchset/pkcs11-provider/blob/f9b04f9e7e200be5e82cf8283a7fb9c4ead0dd37/tests/tcmpkeys.c#L40
that does this (all NULL), but it could be wrong too.
After some more futzing around, fixing things where openssl was not involved,
I was able to *use* a key stored in my [test] (sw)tpm.
(I would suggest that maybe the documentation aimed at provider authors, such
as provider(7), be more clearly separated from provider users. Not sure how
to do that)
Now, I had to create the keys using tpm2_createak and tpm2_evictcontrol.
I don't really like that. I think that the provider interface supports
generating keys, but I don't know how to get it to do that!
I feel that perhaps ruby's generate_parameters, which calls
EVP_PKEY_CTX_new_from_name might let me set the provider explicitely, if I
knew what string to use. Getting the right things out to specify RSA/EC,
curves, bit sizes, etc. was not well explained, and I have patches to
ruby-openssl to update the documentation. That it has to reference the help
page from "openssl genpkey" rather than a somepage(3) seems a documentation bug.
And then there is: EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
but, it mentions ENGINE, not Provider. Not sure what to think. It's not
marked obsolete either.
new_from_{dispatch,name}() takes OSSL_LIB_CTX, but I'm rather unclear if it's for me.
It says:
OSSL_LIB_CTX_new_from_dispatch() creates a new OpenSSL library context
initialised to use callbacks from the OSSL_DISPATCH structure. This is
**PRIMARILY** USEFUL FOR PROVIDER AUTHORS. The handle and dispatch
Maybe secondarily used by others?
Unclear.
Then, we have:
OSSL_PROVIDER_get0_provider_ctx() returns the provider context for the
given provider. The provider context is an opaque handle set by the
provider itself and is passed back to the provider by libcrypto in
various function calls.
but *it* returns a void*, not an OSSL_LIB_CTX. Maybe it's a typo?
A void* could point at an OSSL_LIB_CTX, but it would be wrong that wasn't expected.
From a ruby point of view, what would make sense to me is to load a provider,
and then from the provider object, ask it to produce an EVP_PKEY_CTX.
I'd ask then ask that object to generate an appropriate key, returning an EVP_PKEY.
(Since EVP_PKEY's are supposed to be immutable)
Right now, there is a generate_parameters which returns an **EVP_PKEY**,
[not a new object], and then that is used to generate a key, or it can all be
one step. It is kinda confused, because it tries to handle 1.x and 3.x flow.
I have confirmed that nothing magically uses the tpm2 provider for
generation:
The key I loaded from the TPM handle:
#<OpenSSL::PKey::RSA:0x00007fbe6986ede8 oid=rsaEncryption type_name=RSA provider=tpm2>
The key I generated:
#<OpenSSL::PKey::EC:0x00007fbe6986ea78 oid=id-ecPublicKey type_name=EC provider=default>
(I know one is RSA and one is EC. Just a test. TPM emulator should support
both)
--
] Never tell me the odds! | ipv6 mesh networks [
] Michael Richardson, Sandelman Software Works | IoT architect [
] mcr-SWp7JaYWvAQV+D8aMU/[email protected] http://www.sandelman.ca/ | ruby on rails [
--
You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-users+unsubscribe-MCmKBN63+Bmbup2nOX2J7Q@public.gmane.org
To view this discussion visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/19560.1755047708%40obiwan.sandelman.ca.
signature.asc
(application/pgp-signature, 511 B)
-----BEGIN PGP SIGNATURE----- iQFFBAEBCgAvFiEEbsyLEzg/qUTA43uogItw+93Q3WUFAmib5xwRHG1jckBzYW5k ZWxtYW4uY2EACgkQgItw+93Q3WWgdQgAshYlAZJYgU08gr9nHnd5/5HX5atIc6WS OPrMhHjpb7eKxPWlMOtz6CJtYodqpP+mtHaRZcC69zP+UsOixC43zpAJyCq7b+MH 5kydTxVc+IdCbwpkG1FQMZqUPztZYimlvf0kowXDKOG7j5O30yxQYmTHoRpmjoAK HHIVZciTEDYE6eD+WCCH6UqGfSxDB6W/07nFHq5+7+nlLvelUA6qSCZNaBV54MXL mQ/hsQN4102k15kEEaiU5imSirOuz3lBmAoHabqHa3KXetxcykkdi0GYkn1PU3gn jy5jGGSZyRC5qkzHyaNGplCWnTNhzw30/jU7LvYHFpNboH/13+MhXA== =VOUY -----END PGP SIGNATURE-----