aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_pkey.c
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2021-04-22 16:33:59 +0900
committerKazuki Yamaguchi <k@rhe.jp>2021-12-12 18:23:59 +0900
commit66cd8cbaaf85604a13fd68bd9cd280a2881044ad (patch)
tree2f46515bbc1fcb8a59c596837f10b58ede810e56 /ext/openssl/ossl_pkey.c
parent74f6c6175688502a5bf27ae35367616858630c0f (diff)
downloadruby-openssl-66cd8cbaaf85604a13fd68bd9cd280a2881044ad.tar.gz
pkey: use EVP_PKEY_dup() if availableky/pkey-base-dup
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.
Diffstat (limited to 'ext/openssl/ossl_pkey.c')
-rw-r--r--ext/openssl/ossl_pkey.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index ea75d63f..4599582a 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -491,6 +491,26 @@ ossl_pkey_initialize(VALUE 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:
* pkey.oid -> string
@@ -1468,6 +1488,11 @@ Init_ossl_pkey(void)
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
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, "inspect", ossl_pkey_inspect, 0);
rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0);