Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/openssl/ossl_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)
GetEngine(self, e);
pkey = ENGINE_load_private_key(e, sid, NULL, sdata);
if (!pkey) ossl_raise(eEngineError, NULL);
obj = ossl_pkey_new(pkey);
obj = ossl_pkey_wrap(pkey);
OSSL_PKEY_SET_PRIVATE(obj);

return obj;
Expand Down Expand Up @@ -403,7 +403,7 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)
pkey = ENGINE_load_public_key(e, sid, NULL, sdata);
if (!pkey) ossl_raise(eEngineError, NULL);

return ossl_pkey_new(pkey);
return ossl_pkey_wrap(pkey);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_ns_spki.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ ossl_spki_get_public_key(VALUE self)
ossl_raise(eSPKIError, NULL);
}

return ossl_pkey_new(pkey); /* NO DUP - OK */
return ossl_pkey_wrap(pkey);
}

/*
Expand Down
6 changes: 3 additions & 3 deletions ext/openssl/ossl_pkcs12.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
}

static VALUE
ossl_pkey_new_i(VALUE arg)
ossl_pkey_wrap_i(VALUE arg)
{
return ossl_pkey_new((EVP_PKEY *)arg);
return ossl_pkey_wrap((EVP_PKEY *)arg);
}

static VALUE
Expand Down Expand Up @@ -208,7 +208,7 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(ePKCS12Error, "PKCS12_parse");
ERR_pop_to_mark();
if (key) {
pkey = rb_protect(ossl_pkey_new_i, (VALUE)key, &st);
pkey = rb_protect(ossl_pkey_wrap_i, (VALUE)key, &st);
if (st) goto err;
}
if (x509) {
Expand Down
44 changes: 36 additions & 8 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,44 @@ VALUE mPKey;
VALUE cPKey;
VALUE ePKeyError;
static ID id_private_q;
int ossl_pkey_ex_ptr_idx;

static void
ossl_evp_pkey_mark(void *ptr)
{
VALUE obj = (VALUE)EVP_PKEY_get_ex_data(ptr, ossl_pkey_ex_ptr_idx);
rb_gc_mark_movable(obj);
}

static void
ossl_evp_pkey_free(void *ptr)
{
EVP_PKEY_set_ex_data(ptr, ossl_pkey_ex_ptr_idx, NULL);
EVP_PKEY_free(ptr);
}

static void
ossl_evp_pkey_compact(void *ptr)
{
VALUE obj = (VALUE)EVP_PKEY_get_ex_data(ptr, ossl_pkey_ex_ptr_idx);
EVP_PKEY_set_ex_data(ptr, ossl_pkey_ex_ptr_idx, (void *)rb_gc_location(obj));
}

/*
* Public
*/
const rb_data_type_t ossl_evp_pkey_type = {
"OpenSSL/EVP_PKEY",
{
0, ossl_evp_pkey_free,
.dmark = ossl_evp_pkey_mark,
.dfree = ossl_evp_pkey_free,
.dcompact = ossl_evp_pkey_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

static VALUE
pkey_new0(VALUE arg)
pkey_wrap0(VALUE arg)
{
EVP_PKEY *pkey = (EVP_PKEY *)arg;
VALUE klass, obj;
Expand All @@ -61,16 +79,21 @@ pkey_new0(VALUE arg)
}
obj = rb_obj_alloc(klass);
RTYPEDDATA_DATA(obj) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)obj);
return obj;
}

VALUE
ossl_pkey_new(EVP_PKEY *pkey)
ossl_pkey_wrap(EVP_PKEY *pkey)
{
VALUE obj;
int status;

obj = rb_protect(pkey_new0, (VALUE)pkey, &status);
obj = (VALUE)EVP_PKEY_get_ex_data(pkey, ossl_pkey_ex_ptr_idx);
if (obj)
return obj;

obj = rb_protect(pkey_wrap0, (VALUE)pkey, &status);
if (status) {
EVP_PKEY_free(pkey);
rb_jump_tag(status);
Expand Down Expand Up @@ -239,7 +262,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
BIO_free(bio);
if (!pkey)
ossl_raise(ePKeyError, "Could not parse PKey");
return ossl_pkey_new(pkey);
return ossl_pkey_wrap(pkey);
}

static VALUE
Expand Down Expand Up @@ -443,7 +466,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam)
}
}

return ossl_pkey_new(gen_arg.pkey);
return ossl_pkey_wrap(gen_arg.pkey);
}

/*
Expand Down Expand Up @@ -630,6 +653,7 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other)
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_dup");
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
}
return self;
}
Expand Down Expand Up @@ -664,7 +688,7 @@ ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");

return ossl_pkey_new(pkey);
return ossl_pkey_wrap(pkey);
}
#endif

Expand Down Expand Up @@ -697,7 +721,7 @@ ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");

return ossl_pkey_new(pkey);
return ossl_pkey_wrap(pkey);
}
#endif

Expand Down Expand Up @@ -1678,6 +1702,10 @@ Init_ossl_pkey(void)
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
#endif

ossl_pkey_ex_ptr_idx = EVP_PKEY_get_ex_new_index(0, (void *)"ossl_pkey_ex_ptr_idx", 0, 0, 0);
if (ossl_pkey_ex_ptr_idx < 0)
ossl_raise(rb_eRuntimeError, "EVP_PKEY_get_ex_new_index");

/* Document-module: OpenSSL::PKey
*
* == Asymmetric Public Key Algorithms
Expand Down
4 changes: 3 additions & 1 deletion ext/openssl/ossl_pkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extern VALUE mPKey;
extern VALUE cPKey;
extern VALUE ePKeyError;
extern const rb_data_type_t ossl_evp_pkey_type;
extern int ossl_pkey_ex_ptr_idx;

/* For ENGINE */
#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue)
Expand All @@ -24,10 +25,11 @@ extern const rb_data_type_t ossl_evp_pkey_type;
if (!(pkey)) { \
rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\
} \
RUBY_ASSERT(obj == (VALUE)EVP_PKEY_get_ex_data(pkey, ossl_pkey_ex_ptr_idx)); \
} while (0)

/* Takes ownership of the EVP_PKEY */
VALUE ossl_pkey_new(EVP_PKEY *);
VALUE ossl_pkey_wrap(EVP_PKEY *);
void ossl_pkey_check_public_key(const EVP_PKEY *);
EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE);
EVP_PKEY *GetPKeyPtr(VALUE);
Expand Down
3 changes: 3 additions & 0 deletions ext/openssl/ossl_pkey_dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;

legacy:
Expand All @@ -124,6 +125,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;
}

Expand Down Expand Up @@ -164,6 +166,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions ext/openssl/ossl_pkey_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;

legacy:
Expand All @@ -136,6 +137,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;
}

Expand Down Expand Up @@ -164,6 +166,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);

return self;
}
Expand Down
11 changes: 8 additions & 3 deletions ext/openssl/ossl_pkey_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,18 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
obj = rb_obj_alloc(klass);

ec = ec_key_new_from_group(arg);
if (!EC_KEY_generate_key(ec)) {
EC_KEY_free(ec);
ossl_raise(eECError, "EC_KEY_generate_key");
}
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");
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)obj);

return obj;
}
Expand Down Expand Up @@ -177,6 +179,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;

legacy:
Expand All @@ -187,6 +190,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;
}

Expand All @@ -212,6 +216,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);

return self;
}
Expand Down
3 changes: 3 additions & 0 deletions ext/openssl/ossl_pkey_rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;

legacy:
Expand All @@ -132,6 +133,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);
return self;
}

Expand Down Expand Up @@ -159,6 +161,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
}
RTYPEDDATA_DATA(self) = pkey;
EVP_PKEY_set_ex_data(pkey, ossl_pkey_ex_ptr_idx, (void *)self);

return self;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2575,7 +2575,7 @@ ossl_ssl_tmp_key(VALUE self)
GetSSL(self, ssl);
if (!SSL_get_server_tmp_key(ssl, &key))
return Qnil;
return ossl_pkey_new(key);
return ossl_pkey_wrap(key);
}
#endif /* !defined(OPENSSL_NO_SOCK) */

Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_x509cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ ossl_x509_get_public_key(VALUE self)
ossl_raise(eX509CertError, NULL);
}

return ossl_pkey_new(pkey); /* NO DUP - OK */
return ossl_pkey_wrap(pkey);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_x509req.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ ossl_x509req_get_public_key(VALUE self)
ossl_raise(eX509ReqError, NULL);
}

return ossl_pkey_new(pkey); /* NO DUP - OK */
return ossl_pkey_wrap(pkey);
}

static VALUE
Expand Down
11 changes: 11 additions & 0 deletions test/openssl/test_x509cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ def test_public_key
}
end

def test_public_key_instance
# Repeated calls of X509_get_pubkey() return the same EVP_PKEY object with
# increased reference count
cert = OpenSSL::X509::Certificate.new
cert.public_key = @rsa2048

p1 = cert.public_key
p2 = cert.public_key
assert_same(p1, p2)
end

def test_validity
now = Time.at(Time.now.to_i + 0.9)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil,
Expand Down
Loading