Skip to content

Commit

Permalink
pkey: inline {rsa,dsa,dh,ec}_instance()
Browse files Browse the repository at this point in the history
Merge the code into the callers so that the wrapping Ruby object is
allocated before the raw key object is allocated. This prevents possible
memory leak on Ruby object allocation failure, and also reduces the
lines of code.
  • Loading branch information
rhenium committed May 13, 2020
1 parent 94aeab2 commit 1eb1366
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 156 deletions.
63 changes: 21 additions & 42 deletions ext/openssl/ossl_pkey_dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,6 @@
VALUE cDH;
VALUE eDHError;

/*
* Public
*/
static VALUE
dh_instance(VALUE klass, DH *dh)
{
EVP_PKEY *pkey;
VALUE obj;

if (!dh) {
return Qfalse;
}
obj = NewPKey(klass);
if (!(pkey = EVP_PKEY_new())) {
return Qfalse;
}
if (!EVP_PKEY_assign_DH(pkey, dh)) {
EVP_PKEY_free(pkey);
return Qfalse;
}
SetPKey(obj, pkey);

return obj;
}

/*
* Private
*/
Expand Down Expand Up @@ -84,7 +59,7 @@ dh_generate(int size, int gen)
if (!dh || !cb) {
DH_free(dh);
BN_GENCB_free(cb);
return NULL;
ossl_raise(eDHError, "malloc failure");
}

if (rb_block_given_p())
Expand All @@ -110,12 +85,12 @@ dh_generate(int size, int gen)
ossl_clear_error();
rb_jump_tag(cb_arg.state);
}
return NULL;
ossl_raise(eDHError, "DH_generate_parameters_ex");
}

if (!DH_generate_key(dh)) {
DH_free(dh);
return NULL;
ossl_raise(eDHError, "DH_generate_key");
}

return dh;
Expand All @@ -136,20 +111,22 @@ dh_generate(int size, int gen)
static VALUE
ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
{
EVP_PKEY *pkey;
DH *dh ;
int g = 2;
VALUE size, gen, obj;

if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
g = NUM2INT(gen);
}
obj = rb_obj_alloc(klass);
GetPKey(obj, pkey);

dh = dh_generate(NUM2INT(size), g);
obj = dh_instance(klass, dh);
if (obj == Qfalse) {
DH_free(dh);
ossl_raise(eDHError, NULL);
if (!EVP_PKEY_assign_DH(pkey, dh)) {
DH_free(dh);
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
}

return obj;
}

Expand Down Expand Up @@ -195,9 +172,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
if (!NIL_P(gen)) {
g = NUM2INT(gen);
}
if (!(dh = dh_generate(NUM2INT(arg), g))) {
ossl_raise(eDHError, NULL);
}
dh = dh_generate(NUM2INT(arg), g);
}
else {
arg = ossl_to_der_if_possible(arg);
Expand Down Expand Up @@ -434,17 +409,21 @@ ossl_dh_to_text(VALUE self)
static VALUE
ossl_dh_to_public_key(VALUE self)
{
EVP_PKEY *pkey;
DH *orig_dh, *dh;
VALUE obj;

obj = rb_obj_alloc(rb_obj_class(self));
GetPKey(obj, pkey);

GetDH(self, orig_dh);
dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
obj = dh_instance(rb_obj_class(self), dh);
if (obj == Qfalse) {
DH_free(dh);
ossl_raise(eDHError, NULL);
dh = DHparams_dup(orig_dh);
if (!dh)
ossl_raise(eDHError, "DHparams_dup");
if (!EVP_PKEY_assign_DH(pkey, dh)) {
DH_free(dh);
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
}

return obj;
}

Expand Down
68 changes: 25 additions & 43 deletions ext/openssl/ossl_pkey_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,6 @@ DSA_PRIVATE(VALUE obj, DSA *dsa)
VALUE cDSA;
VALUE eDSAError;

/*
* Public
*/
static VALUE
dsa_instance(VALUE klass, DSA *dsa)
{
EVP_PKEY *pkey;
VALUE obj;

if (!dsa) {
return Qfalse;
}
obj = NewPKey(klass);
if (!(pkey = EVP_PKEY_new())) {
return Qfalse;
}
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
EVP_PKEY_free(pkey);
return Qfalse;
}
SetPKey(obj, pkey);

return obj;
}

/*
* Private
*/
Expand Down Expand Up @@ -100,9 +75,9 @@ dsa_generate(int size)
unsigned long h;

if (!dsa || !cb) {
DSA_free(dsa);
BN_GENCB_free(cb);
return NULL;
DSA_free(dsa);
BN_GENCB_free(cb);
ossl_raise(eDSAError, "malloc failure");
}

if (rb_block_given_p())
Expand Down Expand Up @@ -132,12 +107,12 @@ dsa_generate(int size)
ossl_clear_error();
rb_jump_tag(cb_arg.state);
}
return NULL;
ossl_raise(eDSAError, "DSA_generate_parameters_ex");
}

if (!DSA_generate_key(dsa)) {
DSA_free(dsa);
return NULL;
DSA_free(dsa);
ossl_raise(eDSAError, "DSA_generate_key");
}

return dsa;
Expand All @@ -157,14 +132,18 @@ dsa_generate(int size)
static VALUE
ossl_dsa_s_generate(VALUE klass, VALUE size)
{
DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
VALUE obj = dsa_instance(klass, dsa);
EVP_PKEY *pkey;
DSA *dsa;
VALUE obj;

if (obj == Qfalse) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
}
obj = rb_obj_alloc(klass);
GetPKey(obj, pkey);

dsa = dsa_generate(NUM2INT(size));
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
}
return obj;
}

Expand Down Expand Up @@ -460,20 +439,23 @@ ossl_dsa_to_text(VALUE self)
static VALUE
ossl_dsa_to_public_key(VALUE self)
{
EVP_PKEY *pkey;
EVP_PKEY *pkey, *pkey_new;
DSA *dsa;
VALUE obj;

GetPKeyDSA(self, pkey);
/* err check performed by dsa_instance */
obj = rb_obj_alloc(rb_obj_class(self));
GetPKey(obj, pkey_new);

#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
#undef DSAPublicKey_dup
obj = dsa_instance(rb_obj_class(self), dsa);
if (obj == Qfalse) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
if (!dsa)
ossl_raise(eDSAError, "DSAPublicKey_dup");
if (!EVP_PKEY_assign_DSA(pkey_new, dsa)) {
DSA_free(dsa);
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
}
return obj;
}
Expand Down
34 changes: 7 additions & 27 deletions ext/openssl/ossl_pkey_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,6 @@ static ID id_i_group;
static VALUE ec_group_new(const EC_GROUP *group);
static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group);

static VALUE ec_instance(VALUE klass, EC_KEY *ec)
{
EVP_PKEY *pkey;
VALUE obj;

if (!ec) {
return Qfalse;
}
obj = NewPKey(klass);
if (!(pkey = EVP_PKEY_new())) {
return Qfalse;
}
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
EVP_PKEY_free(pkey);
return Qfalse;
}
SetPKey(obj, pkey);

return obj;
}

/*
* Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
* representing an OID.
Expand Down Expand Up @@ -130,17 +109,18 @@ ec_key_new_from_group(VALUE arg)
static VALUE
ossl_ec_key_s_generate(VALUE klass, VALUE arg)
{
EVP_PKEY *pkey;
EC_KEY *ec;
VALUE obj;

ec = ec_key_new_from_group(arg);
obj = rb_obj_alloc(klass);
GetPKey(obj, pkey);

obj = ec_instance(klass, ec);
if (obj == Qfalse) {
EC_KEY_free(ec);
ossl_raise(eECError, NULL);
ec = ec_key_new_from_group(arg);
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
EC_KEY_free(ec);
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}

if (!EC_KEY_generate_key(ec))
ossl_raise(eECError, "EC_KEY_generate_key");

Expand Down

0 comments on commit 1eb1366

Please sign in to comment.