-
Notifications
You must be signed in to change notification settings - Fork 163
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
Changes from 8 commits
717fe3f
8f7467f
9cf27ac
7b599ca
4e1da3d
8e89a27
46d4fc7
80e9ef1
202cac7
b48fcab
e9ccf58
26bd41d
6628df1
4d67841
edadf2f
f721fd0
18623dd
c40d4fe
23262c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -628,6 +628,71 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) | |
} | ||
#endif | ||
|
||
/* | ||
* call-seq: | ||
* OpenSSL::PKey.private_new(algo, string) -> PKey | ||
* | ||
* See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() | ||
*/ | ||
|
||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
static VALUE | ||
ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) | ||
{ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove this empty line. |
||
EVP_PKEY *pkey; | ||
const EVP_PKEY_ASN1_METHOD *ameth; | ||
int pkey_id; | ||
size_t keylen; | ||
|
||
StringValue(type); | ||
ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); | ||
if (!ameth) | ||
ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); | ||
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); | ||
|
||
keylen = RSTRING_LEN(key); | ||
rhenium marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Fixed @ e9ccf58 |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line has trailing spaces. |
||
return ossl_pkey_new(pkey); | ||
} | ||
#endif | ||
|
||
/* | ||
* call-seq: | ||
* OpenSSL::PKey.public_new(algo, string) -> PKey | ||
* | ||
* See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() | ||
*/ | ||
|
||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
static VALUE | ||
ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) | ||
{ | ||
EVP_PKEY *pkey; | ||
const EVP_PKEY_ASN1_METHOD *ameth; | ||
int pkey_id; | ||
size_t keylen; | ||
|
||
StringValue(type); | ||
ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); | ||
if (!ameth) | ||
ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); | ||
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); | ||
|
||
keylen = RSTRING_LEN(key); | ||
|
||
pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); | ||
if (!pkey) | ||
ossl_raise(ePKeyError, "Could not parse PKey"); | ||
|
||
return ossl_pkey_new(pkey); | ||
} | ||
#endif | ||
|
||
/* | ||
* call-seq: | ||
* pkey.oid -> string | ||
|
@@ -816,6 +881,33 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) | |
return do_pkcs8_export(argc, argv, self, 0); | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* key.private_to_raw => string | ||
* | ||
* See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() | ||
*/ | ||
|
||
#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 commentThe reason will be displayed to describe this comment to others. Learn more. Style nit: please insert a newline after There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed @ 26bd41d |
||
{ | ||
EVP_PKEY *pkey; | ||
VALUE str; | ||
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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Fixed @ 6628df1. |
||
str = rb_str_new(NULL, len); | ||
|
||
if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) | ||
ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); | ||
|
||
rb_str_set_len(str, len); | ||
|
||
return str; | ||
} | ||
#endif | ||
|
||
VALUE | ||
ossl_pkey_export_spki(VALUE self, int to_der) | ||
{ | ||
|
@@ -867,6 +959,34 @@ ossl_pkey_public_to_pem(VALUE self) | |
|
||
/* | ||
* call-seq: | ||
* key.public_to_raw => string | ||
* | ||
* See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() | ||
*/ | ||
|
||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
static VALUE ossl_pkey_public_to_raw(VALUE self) | ||
{ | ||
EVP_PKEY *pkey; | ||
VALUE str; | ||
size_t len; | ||
|
||
GetPKey(self, pkey); | ||
EVP_PKEY_get_raw_public_key(pkey, NULL, &len); | ||
str = rb_str_new(NULL, len); | ||
|
||
if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) | ||
ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); | ||
|
||
rb_str_set_len(str, len); | ||
|
||
return str; | ||
} | ||
#endif | ||
|
||
/* | ||
* call-seq: | ||
* pkey.sign(digest, data) -> String | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line looks like a copy-and-paste error. |
||
* pkey.compare?(another_pkey) -> true | false | ||
* | ||
* Used primarily to check if an OpenSSL::X509::Certificate#public_key compares to its private key. | ||
|
@@ -1602,6 +1722,10 @@ Init_ossl_pkey(void) | |
rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); | ||
rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); | ||
rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); | ||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
rb_define_module_function(mPKey, "private_new", ossl_pkey_initialize_private, 2); | ||
rb_define_module_function(mPKey, "public_new", ossl_pkey_initialize_public, 2); | ||
#endif | ||
|
||
rb_define_alloc_func(cPKey, ossl_pkey_alloc); | ||
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); | ||
|
@@ -1615,8 +1739,14 @@ Init_ossl_pkey(void) | |
rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); | ||
rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); | ||
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); | ||
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY | ||
rb_define_method(cPKey, "private_to_raw", ossl_pkey_private_to_raw, 0); | ||
#endif | ||
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, "public_to_raw", ossl_pkey_public_to_raw, 0); | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we group the |
||
rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); | ||
|
||
rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -310,6 +310,12 @@ def to_bn(conversion_form = group.point_conversion_form) | |
end | ||
end | ||
|
||
class PKey | ||
def self._load(string) | ||
OpenSSL::PKey.read(string) | ||
end | ||
end | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Fixed @ 4d67841 |
||
class RSA | ||
include OpenSSL::Marshal | ||
|
||
|
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.