Re: ruby-openssl + provider interface: generating keys with provider
Michael Richardson <mcr-SWp7JaYWvAQV+D8aMU/[email protected]> Wed, 27 Aug 2025 19:02:45 -0400
| Newsgroups | gmane.comp.encryption.openssl.user |
|---|---|
| Message-ID | <[email protected]> |
Viktor Dukhovni <[email protected]> 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. I don't know if there is semantic subtlety you are trying to get at, but I've missed it. This seems to be semantic pedantry to me. I'm happy to be wrong. I think in 60% of the cases, people building bespoke systems in C, Rust, ruby, python, Perl, ... know exactly what they want, and they are mostly targetting a specific provider. Yes, they might want some agility in moving to a different provider, but they will need to test against those anyway. Their "customers", if they are external, will be told which ones work, and that others are "who knows" until tested. For me, this query string is not only unwanted, but could even be dangerous. 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. I'm working on a bespoke system written RubyOnRails and Rust (different pieces), and to do that I'm trying to make sure that the ruby-openssl library can do what I want. I'd like to benefit as many people as possible, but the query string business is not particularly useful to me. > 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". Yes, but I shouldn't have to throw these strings all over the place. Once is enough. I've traced into crypto/evp/m_sigver.c, to: static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, It's a very complex function. It really deserves some unit tests. I found that the loop gets it wrong. An EVP_MD_CTX has been created a few layers up based upon the EVP_PKEY(_CTX), which has a sensible keymgmt pointing at the provider which has access to the private key. Picking ANY OTHER provider at this point would be stupid, yet the loop manages to do exactly that. The loop starting after the comments at line 116: for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { only runs once. I don't think it should exit the loop when provkey!=NULL. Rather, I think it should run all possibilities, and then it should pick the *best* one, which is not necessarily the first thing. It says: * We then try to fetch the keymgmt from the same provider as the * signature, and try to export |ctx->pkey| to that keymgmt (when * this keymgmt happens to be the same as |ctx->keymgmt|, the export * is a no-op, but we call it anyway to not complicate the code even * more). but, it doesn't do that. Instead, on the first iter=1, it does: signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig, locpctx->propquery); despite libctx and propquery being NULL, so of course, it finds the default provider. I added: if(locpctx->libctx || locpctx->propquery) { } 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. I doubt my fix is correct, but without some unit test cases that actually had complete code coverage, I won't know what the full set of behaviour is. It might be that swapping case 1:/case 2: would work. Or maybe it's the call to: if (tmp_keymgmt != NULL) provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx, &tmp_keymgmt, locpctx->propquery); that is wrong. Maybe that should occur only after the loop finishes. (Again, not ending prematurely) 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. -- ] 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/18581.1756335765%40obiwan.sandelman.ca.
signature.asc
(application/pgp-signature, 511 B)
-----BEGIN PGP SIGNATURE----- iQFFBAEBCgAvFiEEbsyLEzg/qUTA43uogItw+93Q3WUFAmivjpURHG1jckBzYW5k ZWxtYW4uY2EACgkQgItw+93Q3WUMRAgAhL9ZAC6em7kx+CLNR5sFZZl2qimfbyyr kw8vjQFWUxsJJNMDKpy0WQv58hhJK0/dmMAc1co0Xg7G4jr3y0qU/FJpE/ulqhJJ CZGmIcx4IXoDLY/Ovqy9ttmqqyruV33gjiN2y6maTVjcD+qQjjt8a/sdx3+ku3g1 Mrycez280EgBYAU69WoI0w3zfAiXRAMEtAYG8UW+cdQ2KirCFNpMXA5YpKAY6g1T 3QVQOoD8gLqiL1Nvon/bUFKi12IiRqFvFfVSIQLMMrYJTKaJDPFke/KBlhbssprk hf2YbHAFgQ6vICxsetHvSGNpe2WfAlB/wwIKvQrlTbUK8HKgSDoC7Q== =qFAO -----END PGP SIGNATURE-----