[ruby/openssl] pkey: use EVP_PKEY_dup() if available

We can use it to implement OpenSSL::PKey::PKey#initialize_copy. This
should work on all key types, not just DH/DSA/EC/RSA types.

https://github.com/ruby/openssl/commit/66cd8cbaaf
This commit is contained in:
Kazuki Yamaguchi 2021-04-22 16:33:59 +09:00
parent c1a36ebfda
commit df6589e418
6 changed files with 42 additions and 1 deletions

View File

@ -179,6 +179,7 @@ have_func("BN_check_prime")
have_func("EVP_MD_CTX_get0_md") have_func("EVP_MD_CTX_get0_md")
have_func("EVP_MD_CTX_get_pkey_ctx") have_func("EVP_MD_CTX_get_pkey_ctx")
have_func("EVP_PKEY_eq") have_func("EVP_PKEY_eq")
have_func("EVP_PKEY_dup")
Logging::message "=== Checking done. ===\n" Logging::message "=== Checking done. ===\n"

View File

@ -531,6 +531,26 @@ ossl_pkey_initialize(VALUE self)
return self; return self;
} }
#ifdef HAVE_EVP_PKEY_DUP
static VALUE
ossl_pkey_initialize_copy(VALUE self, VALUE other)
{
EVP_PKEY *pkey, *pkey_other;
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
TypedData_Get_Struct(other, EVP_PKEY, &ossl_evp_pkey_type, pkey_other);
if (pkey)
rb_raise(rb_eTypeError, "pkey already initialized");
if (pkey_other) {
pkey = EVP_PKEY_dup(pkey_other);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_dup");
RTYPEDDATA_DATA(self) = pkey;
}
return self;
}
#endif
/* /*
* call-seq: * call-seq:
* pkey.oid -> string * pkey.oid -> string
@ -1508,6 +1528,11 @@ Init_ossl_pkey(void)
rb_define_alloc_func(cPKey, ossl_pkey_alloc); rb_define_alloc_func(cPKey, ossl_pkey_alloc);
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
#ifdef HAVE_EVP_PKEY_DUP
rb_define_method(cPKey, "initialize_copy", ossl_pkey_initialize_copy, 1);
#else
rb_undef_method(cPKey, "initialize_copy");
#endif
rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0);

View File

@ -126,6 +126,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
return self; return self;
} }
#ifndef HAVE_EVP_PKEY_DUP
static VALUE static VALUE
ossl_dh_initialize_copy(VALUE self, VALUE other) ossl_dh_initialize_copy(VALUE self, VALUE other)
{ {
@ -164,6 +165,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
RTYPEDDATA_DATA(self) = pkey; RTYPEDDATA_DATA(self) = pkey;
return self; return self;
} }
#endif
/* /*
* call-seq: * call-seq:
@ -407,7 +409,9 @@ Init_ossl_dh(void)
*/ */
cDH = rb_define_class_under(mPKey, "DH", cPKey); cDH = rb_define_class_under(mPKey, "DH", cPKey);
rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
#ifndef HAVE_EVP_PKEY_DUP
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
#endif
rb_define_method(cDH, "public?", ossl_dh_is_public, 0); rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
rb_define_method(cDH, "private?", ossl_dh_is_private, 0); rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
rb_define_method(cDH, "export", ossl_dh_export, 0); rb_define_method(cDH, "export", ossl_dh_export, 0);

View File

@ -139,6 +139,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
return self; return self;
} }
#ifndef HAVE_EVP_PKEY_DUP
static VALUE static VALUE
ossl_dsa_initialize_copy(VALUE self, VALUE other) ossl_dsa_initialize_copy(VALUE self, VALUE other)
{ {
@ -166,6 +167,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
return self; return self;
} }
#endif
/* /*
* call-seq: * call-seq:
@ -327,7 +329,9 @@ Init_ossl_dsa(void)
cDSA = rb_define_class_under(mPKey, "DSA", cPKey); cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1); rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
#ifndef HAVE_EVP_PKEY_DUP
rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1); rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
#endif
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);

View File

@ -190,6 +190,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
return self; return self;
} }
#ifndef HAVE_EVP_PKEY_DUP
static VALUE static VALUE
ossl_ec_key_initialize_copy(VALUE self, VALUE other) ossl_ec_key_initialize_copy(VALUE self, VALUE other)
{ {
@ -214,6 +215,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
return self; return self;
} }
#endif
/* /*
* call-seq: * call-seq:
@ -1523,8 +1525,9 @@ void Init_ossl_ec(void)
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1); rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1); rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
#ifndef HAVE_EVP_PKEY_DUP
rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1); rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
/* copy/dup/cmp */ #endif
rb_define_method(cEC, "group", ossl_ec_key_get_group, 0); rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1); rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);

View File

@ -135,6 +135,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
return self; return self;
} }
#ifndef HAVE_EVP_PKEY_DUP
static VALUE static VALUE
ossl_rsa_initialize_copy(VALUE self, VALUE other) ossl_rsa_initialize_copy(VALUE self, VALUE other)
{ {
@ -161,6 +162,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
return self; return self;
} }
#endif
/* /*
* call-seq: * call-seq:
@ -535,7 +537,9 @@ Init_ossl_rsa(void)
cRSA = rb_define_class_under(mPKey, "RSA", cPKey); cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
#ifndef HAVE_EVP_PKEY_DUP
rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1); rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
#endif
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);