Thank you very much for the reply.
(Please excuse me if I seem grumpy: there is other unrelated shit)
Viktor Dukhovni <
openss...@dukhovni.org> wrote:
> The distinction is real, I am not in the habit of linguistic pedantry.
> There's a difference between using the EVP API with a properties(7)
> value that fetches algorithm handles from a selected provider, and
> using the **provider API** to directly call the backend provider
> interfaces.
I never had any interest in calling the provider *API* directly.
I guess the word "interface" is the source of confusion.
I mean: the openssl library calls with OSSL_PROVIDER* in them.
Whereas, you understood me to be referring to the interface *from* openssl to
the provider. Which arguably is the _provider interface_
(we call all these things APIs now, often forgetting what the A means,
and openssl is not the application, and probably there are no better TLAs anymore)
I don't think that I ever said I wanted to do that.
I'm sorry I mis-explained.
I've deleted the rest of your EVP_KEY comments, because clearly they do not apply.
I'm saying that the EVP API does not seem capable, and I'm asking for
clarifications, fixes, and only if necessary, amendments.
> What I'm suggesting is that I'm not seeing your so far stated
> requirements as cause to dive into the backend provider API. You
> should be able to do everything you set out to do with the EVP API and
> judicious use of "provider=tpm2" in the `propq` argument of various
> "fetch" calls.
a. It's not enough, because many places do not have propq arguments, or
require propq arguments in places where that code should not care.
b. It's not actually working.
>> In the other 40% of cases, the systems have been built for others to
>> use, and the query string has some significant value because, the
>> systems are not open source (or rather, then people installing them
>> are not installing from source), so a way for the operator to specify
>> the specific provider, and maybe even some parameters to the provider,
>> such as an IP address (in the case of an big-iron HSM) to connect to.
> The IP address of a network HSM would likely be part of the provider
> configuration (load parameters), and would then be implicit in
> subsequent calls to the provider. I would not expect it to have be
> specified when fetching algorithms, signing, verifying, ...
I should be able to load a provider library, then initialize it multiple
times to talk to multiple HSMs. I don't see a place to configure IP
addresses with OSSL_Provider_load, and anyway, that is a handle on the
library, and not the specific configuration. For awhile, I thought
OSSL_LIB_CTX provided that, but I now understand that providers are inside
libctx, not the other way around.
Once configured, I would expect to get a handle that I can now apply to
whatever structures I need (via set() method of course) to do things.
It being NULL would get whatever the system thinks is sane.
>> Yes, but I shouldn't have to throw these strings all over the place.
>> Once is enough.
> If you're sufficiently disinclined to pass explicit `propq` values to
You are asking me to carry around an attribute in my structures which are
already duplicated in the structures I am creating/using. That is, despite
all the variously arcane mechanisms and legacy mecahnism to make providers
"slip in" without changing code, I'm actually supposed to rework everything?
AFAIK, I can't find anything around X509_sign_ctx that takes a propq.
Nor should I: the PKEY already was loaded correctly.
> the relevant API calls, you can, if you prefer, use:
> EVP_set_default_properties(3)
> to set a default. Whichever libctx (or NULL for the default) is the
> one the provider is loaded into, can be set up to make that provider be
> target of all fetch operations. You can then opt out of that default
> with a "local" property of "-provider".
Yeah, that might solve my immediate problem, but it won't solve it for someone
who had two HSMs at different IP addresses using the same provider.
>> around that call, which allowed the second iteration to run, which
>> then did what the comment above promised. The correct signature
>> routine was called, and the key was available.
> To better understand the mismatch between behaviour and expectations, a
> reproducer is needed. Please share minimal demo code that does not do
> what you expect. If you're somewhat confident the EVP implementation
> is not correct, a new issue on Github would be helpful, but a bit of
> demo code in this thread might be a reasonable way to rule out any
> basic misunderstanding.
Sure, I have a short unit test case in my code base.
I've been up-arrow-return on it all week.
But, it's written in ruby, and uses ruby-openssl.
To see it run, it has to initialize ("manufacture") a swtpm, start it, etc.
Which I do in ruby, as part of the test setup/teardown.
But, I can put that all into a shell script.
I can't generate the keys through openssl yet, as I didn't figure out how to make
that work, and I moved on, although I didn't change the subject line enough.
So, to run the test, you'll need the tpm2_* utilities too.
(pause)
I think that the propquery argument to EVP_PKEY_CTX_new_from_name() probably
does the right thing, and I think I can make that work, but last week I didn't see that.
I can probably create an optional propq argument, but it has a smell.
Or a new API.
I think it would be better to allow EVP_PKEY_CTX_ctrl_str() to accept a "provider" control string.
That's what I initially tried based upon my understanding at the time.
I would prefer a EVP_PKEY_CTX_new_from_provider(OSSL_PROVIDER *), or
EVP_PKEY_new_from_provider(OSSL_PROVIDER *). If I have to change my code,
then I'd rather change it to be a bit more object-oriented.
Ruby,Python,Perl wrappers can be more fully OO here.
Again, my earlier comment that much of the man pages, when they discuss
providers, lead rapidly to the reader to wandering into the provider-API documentation,
the stuff aimed at people writing providers.
Which is almost never what the reader wanted.
(As you said: I really don't want to call any of that directly, nor should anyone)
>> In my case, I've created an X509 object that is trying to self-sign
>> the CA public key. You might say that I need to throw propquery
>> strings into that, but that seems very wrong: that part of the code
>> shouldn't need to know where the EVP_PKEY is from, it should just use
>> it.
> Sure, there's no explicit propq in either X509_sign(3) or
> X509_sign_ctx(3), so any implied provider would be associated with the
> key or EVP_MD_CTX. Which of these two functions is the one you're
> using?
The code current uses X509_sign(), which leads to ASN1_item_sign_ex,
which calls evp_md_ctx_new_ex() make an MD_CTX, and the calls sign_ctx().
I see that X509_sign_ctx() has me make the MD_CTX, and the leads to
ASN1_item_sign_ctx() as well.
I will see if I can create an acceptable EVP_MD_CTX.
evp_md_ctx_new_ex() does a lot of things, but it's internal.