-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Use EVP_PKEY for RSA key generation #49336
Conversation
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue DetailsSwitch from using RSA_generate_key_ex to EVP_PKEY_keygen for creating RSA keys. Further changes in this area will get the managed code / shim interaction to a point Contributes to #46526.
|
I appear to have at least a short-term problem in getting this to the top of my attention heap. If you want to point out where the segfault is that'd be helpful. If you want to take this over and drive it to success, that'd be super-duper helpful 😄. |
I'll take a stab at fixing it (can PR in to your fork) but just in case your psychic debugging powers awaken:
Dumping runtime/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c Lines 796 to 798 in 74e3e4b
If I put an |
It looks like that If I just delete this whole runtime/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c Lines 794 to 802 in 74e3e4b
The correct way to check the key type with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested fix for OpenSSL 1.0.2.
if (ctx != NULL) | ||
{ | ||
EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx); | ||
|
||
if (EVP_PKEY_base_id(pkey) != NID_rsaEncryption) | ||
{ | ||
return -1; | ||
} | ||
} | ||
|
||
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (ctx != NULL) | |
{ | |
EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx); | |
if (EVP_PKEY_base_id(pkey) != NID_rsaEncryption) | |
{ | |
return -1; | |
} | |
} | |
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); | |
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2); |
I was trying to write https://github.com/openssl/openssl/blob/081a7061f3da07318c4b0f5de67b82285630bf6b/crypto/rsa/rsa_lib.c#L485-L493. Looks like I missed that ctx->pkey can be NULL. |
@bartonjs ah. Yeah |
I assume |
I'm not sure that really does anything then. It will always be runtime/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c Line 8 in 74e3e4b
|
...
Yeah, it's really these two together that are why I made the local_ as complex as the real thing. The local_ only checks for EVP_PKEY_RSA because it uses Yeah, in the generate flow the pkey is always NULL (which makes me wonder why they routed EVP_PKEY_CTX_set_rsa_keygen_bits through it at all). # define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) # define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) Looks like in 3.0 it's a function in its own right, but I believe the EVP_PKEY_CTX_ctrl route (with or without going through RSA_pkey_ctx_ctrl) will still work.
|
Yeah I guess the question then is what is the right thing for the shim to be doing.
There is no |
Ah. OK, so if we're running in the local_ then we don't need the early failure. Giving that a run, thanks for the help thus far 😄. |
Looks promising. |
} | ||
|
||
EVP_PKEY* pkey = NULL; | ||
int success = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code pattern feels weird to me. Seems like it's too tempting to refactor this to success &= ...
and break the short-circuiting logic.
Isn't if (call1() == 1 && call2() == 1 && call3() == 1)
a more established pattern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I was sort of playing with the syntax a bit looking for "legible and compact", but didn't do it anywhere else in the EVP_PKEY experimentation.
I'll flip it around to look more uniform.
I think you can get rid of the But maybe you'll end up bringing them back in a later PR. |
Yeah, probably. Once all the work for converting to EVP_PKEY is done, and whatever else is needed to be happily working with OpenSSL 3, it's probably time to see how many function binds are no longer necessary. |
Switch from using RSA_generate_key_ex to EVP_PKEY_keygen for creating RSA keys.
This is the preferred model in OpenSSL 3, as it allows for an easier substitute provider
model than the low level primitive.
Further changes in this area will get the managed code / shim interaction to a point
where everything is in terms of
EVP_PKEY*
values instead ofRSA*
values.Among other things, it will allow us to eliminate some of our code from the pipeline,
because the EVP_PKEY interfaces have better support for OAEP and PSS than the primitive.
Contributes to #46526.