Re: ruby-openssl + provider interface: generating keys with provider
Viktor Dukhovni <[email protected]> Sat, 23 Aug 2025 21:02:38 +1000
| Newsgroups | gmane.comp.encryption.openssl.user |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Aug 12, 2025 at 09:15:08PM -0400, Michael Richardson wrote:
> 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.
I am not convinced you really **want** to explicitly "access providers".
Rather, you likely want to have some operations (key generation, loading
a key, signing, ...) performed by a chosen provider. And for that,
appropriate arguments to mainstream EVP APIs should generally be sufficient,
if the desired provider is loaded.
Some relevant text from the openssl-glossary(7) manpage:
Property Query String
A property query string is a string containing a sequence of
properties that can be used to select an algorithm implementation.
For example the query string "provider=example,foo=bar" will select
algorithms from the "example" provider that have a "foo" property
defined for them with a value of "bar".
Property Query Strings are used during fetching. See Fetching.
property(7)
with more detailed text in property(7):
DESCRIPTION
As of OpenSSL 3.0, a new method has been introduced to decide which of
multiple implementations of an algorithm will be used. The method is
centered around the concept of properties. Each implementation defines a
number of properties and when an algorithm is being selected, filters
based on these properties can be used to choose the most appropriate
implementation of the algorithm.
...
> 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.
A PKCS#11 provider may well be a appropriate interface to your TPM, but
if you have an adequate dedicated provider that should be fine too. The
main different will be in how keys are named.
> 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.
I'd start with:
const char *propq = "provider=tpm2";
const char *key_algor = "EC";
OSSL_LIB_CTX *dflt_lctx = NULL;
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(dflt_lctx, key_algor, propq);
EVP_PKEY *pkey = NULL;
OSSL_PARAM params[...];
/*
* Set any required algorithm and/or provider-specific required
* keygen parameters. For EC you'd need at least the curve (a.k.a.
* group) name. For RSA, you'd need the modulus bit length, ...
*/
params[0] = OSSL_PARAM_construct_...(...);
...
params[...] = OSSL_PARAM_construct_...(...);
params[...] = OSSL_PARAM_construct_end();
if (ctx == NULL) {
... error handling ...;
}
if (EVP_PKEY_keygen_init(ctx) <= 0) {
... error handling ...;
}
if (EVP_PKEY_CTX_set_params(ctx, params) != 1) {
... error handling ...;
}
if (EVP_PKEY_generate(ctx, &pkey) <= 0) {
... error handling ...;
}
> 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.
The relevant parameters should be specified in the algorithm and/or
provider docs. If the provider emulates an equivalent "default"
provider interface, than the algorithm docs should suffice, but
otherwise, the provider docs need to explain what the provider expects.
> 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>
It seems your propq should be at least "provider=tpm2".
For relevant key generation parameters see:
https://github.com/tpm2-software/tpm2-openssl/blob/master/docs/keys.md
On Fri, Aug 22, 2025 at 05:07:29PM -0400, Michael Richardson wrote:
> Looking for man pages, and then evp.h, and store.h, to try to learn if there
> is a way to understand if an EVP_PKEY has a private key associated with it.
> I found nothing, but I could perhaps see if it was loaded via a provider, but
> I think that a truism now, because the default provider is still a provider.
Use of existing keys in a hardware device typically requires accessing a
named object in a logical key container associated with that device. So
typically some sort of store URI. This is where PKCS#11 can help
abstract device-specifics, but you can also use the "tpm2" store support
The below CLI example from
<https://github.com/tpm2-software/tpm2-openssl/blob/master/docs/keys.md>:
openssl rsa -provider tpm2 -modulus -noout -in handle:0x81000000
corresponds to loading the "tpm2" "handle" scheme as described in
OSSL_STORE_open_ex(3):
const OSSL_PARAM params[1] = { OSSL_PARAM_END }; /* If none needed */
const char *propq = "provider=tpm2";
const char *key_algor = "EC";
OSSL_LIB_CTX *dflt_lctx = NULL;
OSSL_STORE_CTX *store_ctx =
OSSL_STORE_open_ex("handle:0x81000000, dflt_ctx, propq,
NULL, NULL, /* assuming no passwd required */
params, NULL, NULL);
then use the store to iterate through the returned objects.
--
Viktor. 🇺🇦 Слава Україні!
--
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/aKmfzrAWiwcQ8X2Q%40chardros.imrryr.org.