-
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 support for raw private/public keys #646
Conversation
ext/openssl/ossl_pkey.c
Outdated
int pkey_id; | ||
size_t keylen; | ||
|
||
#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY |
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 doesn't cover the call of EVP_PKEY_new_raw_private_key below so this doesn't prevent a compile error when !HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY.
- [I believe] This kind of error should result into NoMethodError by excluding whole method implementation and declaration.
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.
Thanks for the comment!
The approach in 2. looks good so I went with that in 80e9ef1.
Yes, QUIC (or rather TLS1.3) SHOULD support key exchange with X25519. https://www.rfc-editor.org/rfc/rfc8446.html#section-9.1 This patch helps people who want to implement TLS 1.3. This is what I wanted. |
Thank you for working on this!
Sounds reasonable. It is a difficult task to support marshaling OpenSSL::PKey::PKey because it can be wrapping a wide variety of |
I find the method naming confusing. In my understanding, "raw {private,public} key" is an OpenSSL term to mean the keys specifically used by X25519/Ed25519 family (at least currently), and these new methods are not supposed to work for other PKey types, such as RSA. I want to see the method names reflect it. IMHO, using OpenSSL's function names (with "EVP_PKEY_" and "EVP_PKEY_get_" stripped) just fits here:
What do you think? |
/cc @bdewater |
ext/openssl/ossl_pkey.c
Outdated
* See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() | ||
*/ | ||
|
||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY |
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.
I think #ifdef
needs to be moved above the doc comment so that rdoc can parse it correctly.
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.
Fixed @ 202cac7 .
Maybe the first and second #ifdef
blocks can be merged into one, but I thought having it separated would make it easier to understand that each method needs this condition to be met.
ext/openssl/ossl_pkey.c
Outdated
|
||
pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); | ||
if (!pkey) | ||
ossl_raise(ePKeyError, "Could not parse PKey"); |
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.
The error message should be adjusted because parsing isn't happening here (perhaps just "EVP_PKEY_new_raw_private_key" would work).
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.
Fixed @ e9ccf58
ext/openssl/ossl_pkey.c
Outdated
size_t len; | ||
|
||
GetPKey(self, pkey); | ||
EVP_PKEY_get_raw_private_key(pkey, NULL, &len); |
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 probably needs an error check.
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.
Fixed @ 6628df1.
Maybe we could have a different error message for this call and the next call, but it could be difficult to tell what exactly caused the error on each call so I think leaving as it is now would be reasonable.
ext/openssl/ossl_pkey.c
Outdated
*/ | ||
|
||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
static VALUE ossl_pkey_private_to_raw(VALUE self) |
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.
Style nit: please insert a newline after VALUE
.
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.
Fixed @ 26bd41d
lib/openssl/pkey.rb
Outdated
OpenSSL::PKey.read(string) | ||
end | ||
end | ||
|
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.
Should this be removed too, as this would be unreachable now?
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.
Fixed @ 4d67841
Yes, I think these names would convey the intention that these aren't supposed to be used except for algorithms that support "raw public/private keys". The fixes on the code are as below: |
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.
I added some minor comments, but otherwise it looks good to me!
ext/openssl/ossl_pkey.c
Outdated
static VALUE | ||
ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) | ||
{ | ||
|
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.
Please remove this empty line.
ext/openssl/ossl_pkey.c
Outdated
pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); | ||
if (!pkey) | ||
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); | ||
|
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 line has trailing spaces.
ext/openssl/ossl_pkey.c
Outdated
|
||
/* | ||
* call-seq: | ||
* pkey.sign(digest, data) -> String |
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 line looks like a copy-and-paste error.
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); | ||
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); | ||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); | ||
#endif |
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.
Can we group the #raw_*_key
methods together?
ext/openssl/ossl_pkey.c
Outdated
* See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() | ||
*/ | ||
|
||
static VALUE ossl_pkey_raw_public_key(VALUE self) |
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.
Please insert a newline before the function name.
- Remove trailing whitespaces - Remove extra line break - Styling of function definition - Remove wrong documentation - Group raw_*_key methods together
I've merged this to master now. Thank you! |
(ruby/openssl#646) Add OpenSSL::PKey.new_raw_private_key, #raw_private_key and public equivalents. These methods are useful for importing and exporting keys that support "raw private/public key". Currently, OpenSSL implements X25519/X448 and Ed25519/Ed448 keys. [rhe: rewrote commit message] ruby/openssl@3f29525618 Co-authored-by: Bart de Water <bartdewater@gmail.com>
Thank you both for getting this over the finish line! |
Add OpenSSL::PKey.new_raw_private_key, #raw_private_key and public equivalents. These methods are useful for importing and exporting keys that support "raw private/public key". Currently, OpenSSL implements X25519/X448 and Ed25519/Ed448 keys. [rhe: rewrote commit message] Co-authored-by: Bart de Water <bartdewater@gmail.com>
Based off of #373, applied review comments and fixed tests for older versions.
I removed the
private?
/public?
methods and marshalling support that relies on these methods, as these methods are causing old versions of OpenSSL to not work. I tried fixing these methods, but wasn't able to come up with a consistent fix that works on all versions (out of scope for this PR, but the errors were mostly segfaults on the buffer used inEVP_PKEY_get_raw_private_key
). I am thinking on working on this later, so any advice/support would be appreciated.I would like to first add support for raw private/public keys independently, as these methods are needed to implement protocols that rely on X25519/X448 raw private/public key support (such as Hybrid Public Key Encryption and QUIC).