mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
openssl: add EC.generate
* ext/openssl/ossl_pkey_ec.c (ec_key_new_from_group): Create a new EC_KEY on given EC group. Extracted from ossl_ec_key_initialize(). (ossl_ec_key_s_generate): Added. Create a new EC instance and generate a random private and public key. (ossl_ec_key_initialize): Use ec_key_new_from_group(). (Init_ossl_ec): Define the new method EC.generate. This change is for consistency with other PKey types. [ruby-core:45541] [Bug #6567] * test/openssl/test_pkey_ec.rb: Test that EC.generate works. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55152 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8cbd74a362
commit
85500b6634
3 changed files with 117 additions and 51 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
Wed May 25 01:13:55 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||
|
||||
* ext/openssl/ossl_pkey_ec.c (ec_key_new_from_group): Create a new
|
||||
EC_KEY on given EC group. Extracted from ossl_ec_key_initialize().
|
||||
(ossl_ec_key_s_generate): Added. Create a new EC instance and
|
||||
generate a random private and public key.
|
||||
(ossl_ec_key_initialize): Use ec_key_new_from_group().
|
||||
(Init_ossl_ec): Define the new method EC.generate. This change is
|
||||
for consistency with other PKey types. [ruby-core:45541] [Bug #6567]
|
||||
|
||||
* test/openssl/test_pkey_ec.rb: Test that EC.generate works.
|
||||
|
||||
Wed May 25 00:37:16 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||
|
||||
* ext/openssl/ossl_pkey_ec.c (ossl_ec_key_generate_key): Fix up RDoc.
|
||||
|
|
|
@ -149,6 +149,69 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
|
|||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
|
||||
* representing an OID.
|
||||
*/
|
||||
static EC_KEY *
|
||||
ec_key_new_from_group(VALUE arg)
|
||||
{
|
||||
EC_KEY *ec;
|
||||
|
||||
if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||
EC_GROUP *group;
|
||||
|
||||
SafeRequire_EC_GROUP(arg, group);
|
||||
|
||||
if (!(ec = EC_KEY_new()))
|
||||
ossl_raise(eECError, NULL);
|
||||
|
||||
if (!EC_KEY_set_group(ec, group)) {
|
||||
EC_KEY_free(ec);
|
||||
ossl_raise(eECError, NULL);
|
||||
}
|
||||
} else {
|
||||
int nid = OBJ_sn2nid(StringValueCStr(arg));
|
||||
|
||||
if (nid == NID_undef)
|
||||
ossl_raise(eECError, "invalid curve name");
|
||||
|
||||
if (!(ec = EC_KEY_new_by_curve_name(nid)))
|
||||
ossl_raise(eECError, NULL);
|
||||
|
||||
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
||||
EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
|
||||
}
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* EC.generate(ec_group) -> ec
|
||||
* EC.generate(string) -> ec
|
||||
*
|
||||
* Creates a new EC instance with a new random private and public key.
|
||||
*/
|
||||
static VALUE
|
||||
ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
||||
{
|
||||
EC_KEY *ec;
|
||||
VALUE obj;
|
||||
|
||||
ec = ec_key_new_from_group(arg);
|
||||
|
||||
obj = ec_instance(klass, ec);
|
||||
if (obj == Qfalse) {
|
||||
EC_KEY_free(ec);
|
||||
ossl_raise(eECError, NULL);
|
||||
}
|
||||
|
||||
if (!EC_KEY_generate_key(ec))
|
||||
ossl_raise(eECError, "EC_KEY_generate_key");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* OpenSSL::PKey::EC.new()
|
||||
|
@ -165,9 +228,8 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
|
|||
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *ec = NULL;
|
||||
EC_KEY *ec;
|
||||
VALUE arg, pass;
|
||||
VALUE group = Qnil;
|
||||
|
||||
GetPKey(self, pkey);
|
||||
if (pkey->pkey.ec)
|
||||
|
@ -176,58 +238,43 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||
|
||||
if (NIL_P(arg)) {
|
||||
ec = EC_KEY_new();
|
||||
if (!(ec = EC_KEY_new()))
|
||||
ossl_raise(eECError, NULL);
|
||||
} else if (rb_obj_is_kind_of(arg, cEC)) {
|
||||
EC_KEY *other_ec = NULL;
|
||||
|
||||
SafeRequire_EC_KEY(arg, other_ec);
|
||||
if (!(ec = EC_KEY_dup(other_ec)))
|
||||
ossl_raise(eECError, NULL);
|
||||
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||
ec = ec_key_new_from_group(arg);
|
||||
} else {
|
||||
if (rb_obj_is_kind_of(arg, cEC)) {
|
||||
EC_KEY *other_ec = NULL;
|
||||
BIO *in;
|
||||
|
||||
SafeRequire_EC_KEY(arg, other_ec);
|
||||
ec = EC_KEY_dup(other_ec);
|
||||
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||
ec = EC_KEY_new();
|
||||
group = arg;
|
||||
} else {
|
||||
BIO *in;
|
||||
pass = ossl_pem_passwd_value(pass);
|
||||
in = ossl_obj2bio(arg);
|
||||
|
||||
pass = ossl_pem_passwd_value(pass);
|
||||
in = ossl_obj2bio(arg);
|
||||
ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
||||
}
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = d2i_ECPrivateKey_bio(in, NULL);
|
||||
}
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = d2i_EC_PUBKEY_bio(in, NULL);
|
||||
}
|
||||
BIO_free(in);
|
||||
|
||||
ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
||||
}
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = d2i_ECPrivateKey_bio(in, NULL);
|
||||
}
|
||||
if (!ec) {
|
||||
OSSL_BIO_reset(in);
|
||||
ec = d2i_EC_PUBKEY_bio(in, NULL);
|
||||
}
|
||||
|
||||
BIO_free(in);
|
||||
|
||||
if (ec == NULL) {
|
||||
const char *name = StringValueCStr(arg);
|
||||
int nid = OBJ_sn2nid(name);
|
||||
|
||||
ossl_clear_error(); /* ignore errors in the previous d2i_EC_PUBKEY_bio() */
|
||||
if (nid == NID_undef)
|
||||
ossl_raise(eECError, "unknown curve name (%"PRIsVALUE")", arg);
|
||||
|
||||
if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)
|
||||
ossl_raise(eECError, "unable to create curve (%"PRIsVALUE")\n", arg);
|
||||
|
||||
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
||||
EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
|
||||
}
|
||||
}
|
||||
if (!ec) {
|
||||
ossl_clear_error();
|
||||
ec = ec_key_new_from_group(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (ec == NULL)
|
||||
ossl_raise(eECError, NULL);
|
||||
|
||||
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
EC_KEY_free(ec);
|
||||
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
|
@ -235,9 +282,6 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|||
|
||||
rb_iv_set(self, "@group", Qnil);
|
||||
|
||||
if (!NIL_P(group))
|
||||
rb_funcall(self, rb_intern("group="), 1, arg);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -1620,6 +1664,7 @@ void Init_ossl_ec(void)
|
|||
|
||||
rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0);
|
||||
|
||||
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
|
||||
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
|
||||
/* copy/dup/cmp */
|
||||
|
||||
|
|
|
@ -38,6 +38,15 @@ class OpenSSL::TestEC < OpenSSL::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_generate
|
||||
assert_raise(OpenSSL::PKey::ECError) { OpenSSL::PKey::EC.generate("non-existent") }
|
||||
g = OpenSSL::PKey::EC::Group.new("prime256v1")
|
||||
ec = OpenSSL::PKey::EC.generate(g)
|
||||
assert_equal(true, ec.private?)
|
||||
ec = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
assert_equal(true, ec.private?)
|
||||
end
|
||||
|
||||
def test_check_key
|
||||
for key in @keys
|
||||
assert_equal(true, key.check_key)
|
||||
|
|
Loading…
Reference in a new issue