Re: determining of an EVP_PKEY can do a signature.

Tomas Mraz <[email protected]> Mon, 25 Aug 2025 10:21:55 +0200
Newsgroups gmane.comp.encryption.openssl.user
Message-ID <[email protected]>
On Fri, 2025-08-22 at 17:07 -0400, Michael Richardson wrote:
> 
> Hi, the ruby-openssl code has a check:
>   EVP_PKEY *
>   GetPrivPKeyPtr(VALUE obj)
> 
> which is used in the .sign function.
> It throws an exception if one tries to do a signature without a
> private key.
> Alas, it checks a bunch of internal things, but tries things like
> RSA_get0_key() if it's an RSA key, etc.  (Since ruby has
> OpenSSL::PKey::{RSA,EC,..})
> This clearly is WRONG in a provider world where a private key might
> be kept
> safely away from muggles like me.
> 
> 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.
> 
> Okay, step back.
> What we really want to know is: can this EVP_PKEY perform a signature
> operation.
> It seems that perhaps I should just skip the tests that
> GetPrivPKeyPtr does,
> and just depend upon EVP_DigestSignInit() failing if it can't be
> done?

There is a EVP_PKEY_can_sign(const EVP_PKEY *pkey) function which will
give you answer, whether the key type can be used for signing. However
it won't check whether there actually is a private key held by the pkey
object.

We do have a provider API call (the has() function) to discover that
but that is not directly exposed via EVP API. Furthermore there might
be other reasons (in 3rd party providers) why a key cannot be used for
signing such as access rights or similar.

You can use EVP_PKEY_can_sign() as a sort of pre-check but then you
still need to check the result of EVP_DigestSignInit() which can only
give you the definitive answer.

> EVP_DigestSignInit() still has ENGINE* argument.
> While EVP_DigestSignInit_ex() has OSSL_LIB_CTX.
> I find this confusing!

The EVP_DigestSignInit() function pre-dates the providers and library
contexts, but it will still work with provider-based keys (with the
default library context).

EVP_DigestSignInit_ex() has to be used if you need non-default library
context.

-- 
Tomáš Mráz, Public Support and Security Manager, OpenSSL Foundation
Join the Code Protectors or support us on Github Sponsors
https://openssl-foundation.org/donate/

-- 
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/57e1834035e9a9e603f916f03d3093f883f83495.camel%40openssl.org.