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.