Skip to content

Commit 66cd8cb

Browse files
committed
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.
1 parent 74f6c61 commit 66cd8cb

File tree

6 files changed

+42
-1
lines changed

6 files changed

+42
-1
lines changed

ext/openssl/extconf.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ def find_openssl_library
179179
have_func("EVP_MD_CTX_get0_md")
180180
have_func("EVP_MD_CTX_get_pkey_ctx")
181181
have_func("EVP_PKEY_eq")
182+
have_func("EVP_PKEY_dup")
182183

183184
Logging::message "=== Checking done. ===\n"
184185

ext/openssl/ossl_pkey.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,26 @@ ossl_pkey_initialize(VALUE self)
491491
return self;
492492
}
493493

494+
#ifdef HAVE_EVP_PKEY_DUP
495+
static VALUE
496+
ossl_pkey_initialize_copy(VALUE self, VALUE other)
497+
{
498+
EVP_PKEY *pkey, *pkey_other;
499+
500+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
501+
TypedData_Get_Struct(other, EVP_PKEY, &ossl_evp_pkey_type, pkey_other);
502+
if (pkey)
503+
rb_raise(rb_eTypeError, "pkey already initialized");
504+
if (pkey_other) {
505+
pkey = EVP_PKEY_dup(pkey_other);
506+
if (!pkey)
507+
ossl_raise(ePKeyError, "EVP_PKEY_dup");
508+
RTYPEDDATA_DATA(self) = pkey;
509+
}
510+
return self;
511+
}
512+
#endif
513+
494514
/*
495515
* call-seq:
496516
* pkey.oid -> string
@@ -1468,6 +1488,11 @@ Init_ossl_pkey(void)
14681488

14691489
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
14701490
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
1491+
#ifdef HAVE_EVP_PKEY_DUP
1492+
rb_define_method(cPKey, "initialize_copy", ossl_pkey_initialize_copy, 1);
1493+
#else
1494+
rb_undef_method(cPKey, "initialize_copy");
1495+
#endif
14711496
rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
14721497
rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
14731498
rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0);

ext/openssl/ossl_pkey_dh.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
126126
return self;
127127
}
128128

129+
#ifndef HAVE_EVP_PKEY_DUP
129130
static VALUE
130131
ossl_dh_initialize_copy(VALUE self, VALUE other)
131132
{
@@ -164,6 +165,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
164165
RTYPEDDATA_DATA(self) = pkey;
165166
return self;
166167
}
168+
#endif
167169

168170
/*
169171
* call-seq:
@@ -407,7 +409,9 @@ Init_ossl_dh(void)
407409
*/
408410
cDH = rb_define_class_under(mPKey, "DH", cPKey);
409411
rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
412+
#ifndef HAVE_EVP_PKEY_DUP
410413
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
414+
#endif
411415
rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
412416
rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
413417
rb_define_method(cDH, "export", ossl_dh_export, 0);

ext/openssl/ossl_pkey_dsa.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
139139
return self;
140140
}
141141

142+
#ifndef HAVE_EVP_PKEY_DUP
142143
static VALUE
143144
ossl_dsa_initialize_copy(VALUE self, VALUE other)
144145
{
@@ -166,6 +167,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
166167

167168
return self;
168169
}
170+
#endif
169171

170172
/*
171173
* call-seq:
@@ -327,7 +329,9 @@ Init_ossl_dsa(void)
327329
cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
328330

329331
rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
332+
#ifndef HAVE_EVP_PKEY_DUP
330333
rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
334+
#endif
331335

332336
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
333337
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);

ext/openssl/ossl_pkey_ec.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
190190
return self;
191191
}
192192

193+
#ifndef HAVE_EVP_PKEY_DUP
193194
static VALUE
194195
ossl_ec_key_initialize_copy(VALUE self, VALUE other)
195196
{
@@ -214,6 +215,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
214215

215216
return self;
216217
}
218+
#endif
217219

218220
/*
219221
* call-seq:
@@ -1523,8 +1525,9 @@ void Init_ossl_ec(void)
15231525

15241526
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
15251527
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
1528+
#ifndef HAVE_EVP_PKEY_DUP
15261529
rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
1527-
/* copy/dup/cmp */
1530+
#endif
15281531

15291532
rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
15301533
rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);

ext/openssl/ossl_pkey_rsa.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
135135
return self;
136136
}
137137

138+
#ifndef HAVE_EVP_PKEY_DUP
138139
static VALUE
139140
ossl_rsa_initialize_copy(VALUE self, VALUE other)
140141
{
@@ -161,6 +162,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
161162

162163
return self;
163164
}
165+
#endif
164166

165167
/*
166168
* call-seq:
@@ -535,7 +537,9 @@ Init_ossl_rsa(void)
535537
cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
536538

537539
rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
540+
#ifndef HAVE_EVP_PKEY_DUP
538541
rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
542+
#endif
539543

540544
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
541545
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);

0 commit comments

Comments
 (0)