-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add wrapper method for EVP_PKEY_cmp to compare same type keys #383
Conversation
Ideally these are added to PKey and overridden in subtypes, but my time is limited and not sure if this approach is desired @rhenium |
Do you have some use cases in mind? Implementing proper comparison methods on pkey objects can be tricky because the EVP_PKEY is an abstraction interface. The key components are not necessarily accessible from us if the pkey object is not using OpenSSL's default implementation - for example, HSM-backed keys as created by OpenSSL::Engine#load_private_key. It's even more complicated for RSA, DSA, DH, and EC_KEY as they have another layer of abstraction each (which is being deprecated in favor of EVP_PKEY's, but they still exist). Because of the reason above, it's not possible to properly define equality on all pkeys. Would it be still useful if they can return |
Yes, in one of our apps we generate certificate signing requests which in turn will have a user upload a X509 certificate in which we wish to validate its RSA public key matches that of the RSA private key it corresponds too. Golang: https://github.com/golang/go/blob/master/src/crypto/rsa/rsa.go#L62 I'm not sure I follow. I understand that EVP abstracts away details, but it itself stores knowledge of the alg used via its type attribute which can be fetched via EVP_PKEY_id https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_id.html. Using the pkey's type in a switch/case you could then call into the corresponding match. Example
One would then need to implement the remaining algs comparison methods to have completeness. |
I think we should add a wrapper for EVP_PKEY_cmp(), which is exactly for this purpose and should take care of the various backends. I'd like it to have a different from
Just to clarify, the abstraction is not limited to this and allows use of different implementations of cryptographic algorithms, such as an HSM. In that case, OpenSSL will not have access to the actual key components, and RSA_get0_key() will only return a fake value or NULL. |
Ah true. https://www.openssl.org/docs/man1.0.2/man3/EVP_PKEY_cmp.html is certainly what I'm looking for for my use case and is the cleaner/correct solution. Gotcha, the goal was to resemble obj.eql?, but wasn't aware of the convention not to raise. Will change to public_match?. This would take care of the public_match? case, but not the private. I don't have a need for a private match, but felt like throwing it in there in the event someone else does. As well as providing the 'smarter' comparison func With the knowledge of EVP_PKEY_cmp I'm going to revisit my approach to include it and probably exclude the private_match portion for now. |
Think we discussed something similar in another PR, is this in reference to where they may provide their own 'engine' ? At which point the engine should implement the comparison methods and openssl EVP_PKEY_cmp should wrap the corresponding engine methods? So if one fails to implement such methods on their engine they shouldn't be surprised to see it not function correctly? If that is the case curious if there is a way to check from openssl if the methods are implemented on the engine else we could raise NotImplemented with a hint to check their engine's implementation. |
Alrighty, so after some light reading on the openssl source it would seem |
f623003
to
ba39137
Compare
@rhenium, updated to use EVP_PKEY_cmp. I did not override match in RSA given I'm not sure why openssl chose not to add a param_cmp, but ideally that functionality is added there instead of here. I'm trying to think of a better method than Lastly I noticed the public_key that is returned on EC is the underlying EC::Point instead of an EVP_PKEY. This leads to different behavior when interacting with EC Keys. Not sure if that was intended or what, but wanted to point it out. |
RSA doesn't have the concept of "parameters". We can add a wrapper for EVP_PKEY_cmp_parameters() too, for other algorithms, but I don't know of any use case. I think we can add later when such a need arises.
Just to clarify, EVP_PKEY_cmp() compares the public portions of the two given pkeys only. So it would be the same as what |
That was just an example and we don't have the need to stick to the word "match". However since it compares the public portions only,
It's a known issue/inconsistency. #29 |
Also a documentation for the method is needed. |
The RSA params should be defined in rsa_asn1.c
However, I don't know why they didn't add a param_cmp method to it. Could inquire in openssl, but given I'm not needing it, agree, I'll just leave as is until someone else does. Hmm, are you sure about that? Checking 1.0.2v I see this in p_lib.c
Notice
|
I like Ah gotcha. |
The "parameters" that EVP_PKEY_cmp_parameters() is referring to simply doesn't exist in RSA. |
I checked the docs. EVP_PKEY_cmp(3) says:
So, the -1 is indeed type mismatch for both EVP_PKEY_cmp() and EVP_PKEY_cmp_parameters(). However, EVP_PKEY_ASN1_METHOD(3) allows param_cmp to return an arbitrary negative number.
It seems there is some confusion in the docs. At least, it sounds unusual to me that a -1 return means a specific error. I think we should check the type mismatch explicitly, and check for 1, 0, -2 return and treat everything else as a generic error. |
Ah good eye. Wonder if they meant anything less than -2 for other errors. I'll add the explicit type check in the event someone implemented the param_cmp with some error for -1. |
I figured the params were the ones mentioned above similar to DSA's implementation. It's exactly how I handled it in the original PR.
In this case they could have created a |
Please squash commits into one, and this is good to merge. Thanks! |
Explicitly check for type given some conflicting statements within openssl's documentation around EVP_PKEY_cmp and EVP_PKEY_ASN1_METHOD(3). Add documentation with an example for compare?
43a07e9
to
0bf51da
Compare
Thanks for the review/feedback. Done |
Thank you! |
No description provided.