summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_pkey_ec.c
diff options
context:
space:
mode:
authorKazuki Yamaguchi <[email protected]>2021-04-12 18:32:40 +0900
committerKazuki Yamaguchi <[email protected]>2021-12-20 23:42:01 +0900
commitc1a36ebfda8ba570173e2844bc584786852e6190 (patch)
treeb5f1283466a59a24c3865bc683b10f5362b790fb /ext/openssl/ossl_pkey_ec.c
parent02a58fbfd1406acde30bb7ca4d019f2bd09bfacd (diff)
[ruby/openssl] pkey: allocate EVP_PKEY on #initialize
Allocate an EVP_PKEY when the content is ready: when #initialize or #initialize_copy is called, rather than when a T_DATA is allocated. This is more natural because the lower level API has been deprecated and an EVP_PKEY is becoming the minimum unit of handling keys. https://github.com/ruby/openssl/commit/74f6c61756
Diffstat (limited to 'ext/openssl/ossl_pkey_ec.c')
-rw-r--r--ext/openssl/ossl_pkey_ec.c91
1 files changed, 50 insertions, 41 deletions
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index db80d112a0..71e63969e7 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -109,13 +109,16 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
VALUE obj;
obj = rb_obj_alloc(klass);
- GetPKey(obj, pkey);
ec = ec_key_new_from_group(arg);
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
+ pkey = EVP_PKEY_new();
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
+ EVP_PKEY_free(pkey);
EC_KEY_free(ec);
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}
+ RTYPEDDATA_DATA(obj) = pkey;
+
if (!EC_KEY_generate_key(ec))
ossl_raise(eECError, "EC_KEY_generate_key");
@@ -136,51 +139,54 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
- EC_KEY *ec = NULL;
+ EC_KEY *ec;
+ BIO *in;
VALUE arg, pass;
+ int type;
- GetPKey(self, pkey);
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
- ossl_raise(eECError, "EC_KEY already initialized");
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
+ if (pkey)
+ rb_raise(rb_eTypeError, "pkey already initialized");
rb_scan_args(argc, argv, "02", &arg, &pass);
-
if (NIL_P(arg)) {
if (!(ec = EC_KEY_new()))
- ossl_raise(eECError, NULL);
- } else if (rb_obj_is_kind_of(arg, cEC)) {
- EC_KEY *other_ec = NULL;
+ ossl_raise(eECError, "EC_KEY_new");
+ goto legacy;
+ }
+ else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
+ ec = ec_key_new_from_group(arg);
+ goto legacy;
+ }
- GetEC(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 {
- BIO *in = ossl_obj2bio(&arg);
- EVP_PKEY *tmp;
- pass = ossl_pem_passwd_value(pass);
- tmp = ossl_pkey_read_generic(in, pass);
- if (tmp) {
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC)
- rb_raise(eECError, "incorrect pkey type: %s",
- OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
- ec = EVP_PKEY_get1_EC_KEY(tmp);
- EVP_PKEY_free(tmp);
- }
- BIO_free(in);
+ pass = ossl_pem_passwd_value(pass);
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(&arg);
- if (!ec) {
- ossl_clear_error();
- ec = ec_key_new_from_group(arg);
- }
+ pkey = ossl_pkey_read_generic(in, pass);
+ BIO_free(in);
+ if (!pkey) {
+ ossl_clear_error();
+ ec = ec_key_new_from_group(arg);
+ goto legacy;
}
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
- EC_KEY_free(ec);
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
+ type = EVP_PKEY_base_id(pkey);
+ if (type != EVP_PKEY_EC) {
+ EVP_PKEY_free(pkey);
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
+ RTYPEDDATA_DATA(self) = pkey;
+ return self;
+ legacy:
+ pkey = EVP_PKEY_new();
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
+ EVP_PKEY_free(pkey);
+ EC_KEY_free(ec);
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
+ }
+ RTYPEDDATA_DATA(self) = pkey;
return self;
}
@@ -190,18 +196,21 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
EVP_PKEY *pkey;
EC_KEY *ec, *ec_new;
- GetPKey(self, pkey);
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
- ossl_raise(eECError, "EC already initialized");
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
+ if (pkey)
+ rb_raise(rb_eTypeError, "pkey already initialized");
GetEC(other, ec);
ec_new = EC_KEY_dup(ec);
if (!ec_new)
ossl_raise(eECError, "EC_KEY_dup");
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
- EC_KEY_free(ec_new);
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
+
+ pkey = EVP_PKEY_new();
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) {
+ EC_KEY_free(ec_new);
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}
+ RTYPEDDATA_DATA(self) = pkey;
return self;
}