From 4846facb5f35ff04bd48eadbef0b366e4ffb6234 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Tue, 26 Apr 2016 23:42:20 +0900 Subject: ext/openssl: EVP_PKEY, DH, DSA, RSA, EC_KEY are made opaque Use EVP_PKEY_get0_* instead of pkey->pkey.* Use EVP_PKEY_base_id(pkey) instead of EVP_PKEY_type(pkey->type) Because of this, we can no longer set the parameters/keys directly, and the newly added functions as alternative require setting all relevant values at the same time. So this patch contains incompatibility: the following code no longer works (if using 1.1.0): dh = OpenSSL::PKey::DH.new(...) dh.priv_key = OpenSSL::BN.new(...) ...and we have to write like: dh = OpenSSL::PKey::DH.new(...) priv = OpenSSL::BN.new(...) pub = dh.set_key(pub, priv) --- ext/openssl/ossl_pkey_dh.c | 78 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 37 deletions(-) (limited to 'ext/openssl/ossl_pkey_dh.c') diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index 8704d96611..550f48c7eb 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -7,25 +7,20 @@ * This program is licensed under the same licence as Ruby. * (See the file 'LICENCE'.) */ -#if !defined(OPENSSL_NO_DH) - #include "ossl.h" +#if !defined(OPENSSL_NO_DH) + #define GetPKeyDH(obj, pkey) do { \ GetPKey((obj), (pkey)); \ - if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DH) { /* PARANOIA? */ \ + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \ ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ } \ } while (0) -#define DH_HAS_PRIVATE(dh) ((dh)->priv_key) - -#if !defined(OPENSSL_NO_ENGINE) -# define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine) -#else -# define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh) -#endif - +/* we don't use q */ +#define DH_get0_pg(obj, p, g) DH_get0_pqg(obj, p, NULL, g) +#define DH_set0_pg(obj, p, g) DH_set0_pqg(obj, p, NULL, g) /* * Classes @@ -67,7 +62,7 @@ ossl_dh_new(EVP_PKEY *pkey) obj = dh_instance(cDH, DH_new()); } else { obj = NewPKey(cDH); - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) { + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { ossl_raise(rb_eTypeError, "Not a DH key!"); } SetPKey(obj, pkey); @@ -82,6 +77,10 @@ ossl_dh_new(EVP_PKEY *pkey) /* * Private */ + +OSSL_PKEY_BN_DEF2(dh, DH, pg, p, g) +OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key) + struct dh_blocking_gen_arg { DH *dh; int size; @@ -249,11 +248,15 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_dh_is_public(VALUE self) { + BIGNUM *bn; EVP_PKEY *pkey; + DH *dh; GetPKeyDH(self, pkey); + dh = EVP_PKEY_get0_DH(pkey); + DH_get0_key(dh, &bn, NULL); - return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse; + return bn ? Qtrue : Qfalse; } /* @@ -266,11 +269,19 @@ ossl_dh_is_public(VALUE self) static VALUE ossl_dh_is_private(VALUE self) { + BIGNUM *bn; EVP_PKEY *pkey; + DH *dh; GetPKeyDH(self, pkey); + dh = EVP_PKEY_get0_DH(pkey); + DH_get0_key(dh, &bn, NULL); - return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse; +#if !defined(OPENSSL_NO_ENGINE) + return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse; +#else + return bn ? Qtrue : Qfalse; +#endif } /* @@ -294,7 +305,7 @@ ossl_dh_export(VALUE self) if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(eDHError, NULL); } - if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) { + if (!PEM_write_bio_DHparams(out, EVP_PKEY_get0_DH(pkey))) { BIO_free(out); ossl_raise(eDHError, NULL); } @@ -321,11 +332,11 @@ ossl_dh_to_der(VALUE self) VALUE str; GetPKeyDH(self, pkey); - if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0) + if((len = i2d_DHparams(EVP_PKEY_get0_DH(pkey), NULL)) <= 0) ossl_raise(eDHError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); - if(i2d_DHparams(pkey->pkey.dh, &p) < 0) + if(i2d_DHparams(EVP_PKEY_get0_DH(pkey), &p) < 0) ossl_raise(eDHError, NULL); ossl_str_adjust(str, p); @@ -343,17 +354,12 @@ ossl_dh_to_der(VALUE self) static VALUE ossl_dh_get_params(VALUE self) { - EVP_PKEY *pkey; - VALUE hash; + VALUE hash = rb_hash_new(); - GetPKeyDH(self, pkey); - - hash = rb_hash_new(); - - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key)); + rb_hash_aset(hash, rb_str_new2("p"), ossl_dh_get_p(self)); + rb_hash_aset(hash, rb_str_new2("g"), ossl_dh_get_g(self)); + rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_dh_get_pub_key(self)); + rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_dh_get_priv_key(self)); return hash; } @@ -377,7 +383,7 @@ ossl_dh_to_text(VALUE self) if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(eDHError, NULL); } - if (!DHparams_print(out, pkey->pkey.dh)) { + if (!DHparams_print(out, EVP_PKEY_get0_DH(pkey))) { BIO_free(out); ossl_raise(eDHError, NULL); } @@ -415,7 +421,7 @@ ossl_dh_to_public_key(VALUE self) VALUE obj; GetPKeyDH(self, pkey); - dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */ + dh = DHparams_dup(EVP_PKEY_get0_DH(pkey)); /* err check perfomed by dh_instance */ obj = dh_instance(CLASS_OF(self), dh); if (obj == Qfalse) { DH_free(dh); @@ -441,7 +447,7 @@ ossl_dh_check_params(VALUE self) int codes; GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; + dh = EVP_PKEY_get0_DH(pkey); if (!DH_check(dh, &codes)) { return Qfalse; @@ -473,7 +479,7 @@ ossl_dh_generate_key(VALUE self) EVP_PKEY *pkey; GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; + dh = EVP_PKEY_get0_DH(pkey); if (!DH_generate_key(dh)) ossl_raise(eDHError, "Failed to generate key"); @@ -501,7 +507,7 @@ ossl_dh_compute_key(VALUE self, VALUE pub) int len; GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; + dh = EVP_PKEY_get0_DH(pkey); pub_key = GetBNPtr(pub); len = DH_size(dh); str = rb_str_new(0, len); @@ -513,11 +519,6 @@ ossl_dh_compute_key(VALUE self, VALUE pub) return str; } -OSSL_PKEY_BN(dh, p) -OSSL_PKEY_BN(dh, g) -OSSL_PKEY_BN(dh, pub_key) -OSSL_PKEY_BN(dh, priv_key) - /* * INIT */ @@ -582,6 +583,9 @@ Init_ossl_dh(void) DEF_OSSL_PKEY_BN(cDH, dh, g); DEF_OSSL_PKEY_BN(cDH, dh, pub_key); DEF_OSSL_PKEY_BN(cDH, dh, priv_key); + rb_define_method(cDH, "set_pg", ossl_dh_set_pg, 2); + rb_define_method(cDH, "set_key", ossl_dh_set_key, 2); + rb_define_method(cDH, "params", ossl_dh_get_params, 0); } -- cgit v1.2.3