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.
- 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.
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.
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.
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.
The error message should be adjusted because parsing isn't happening here (perhaps just "EVP_PKEY_new_raw_private_key" would work).
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.
This probably needs an error check.
There was a problem hiding this comment.
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.
Style nit: please insert a newline after VALUE.
lib/openssl/pkey.rb
Outdated
| OpenSSL::PKey.read(string) | ||
| end | ||
| end | ||
|
|
There was a problem hiding this comment.
Should this be removed too, as this would be unreachable now?
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: |
rhenium
left a comment
There was a problem hiding this comment.
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) | ||
| { | ||
|
|
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"); | ||
|
|
ext/openssl/ossl_pkey.c
Outdated
|
|
||
| /* | ||
| * call-seq: | ||
| * pkey.sign(digest, data) -> String |
There was a problem hiding this comment.
This line looks like a copy-and-paste error.
| 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.
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.
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).