diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-12-16 11:41:45 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-01-20 15:27:45 +0900 |
commit | 0ec8143492cf1801bd210b52918da1b387510011 (patch) | |
tree | 0da7b710ffcd7ff2d4688006708d8bb6f0739e3b | |
parent | 5c586acc387834ab4e09260937dc21064fc59de4 (diff) | |
download | ruby-openssl-topic/pkey-dh-generate-key-length.tar.gz |
pkey: allow specifying size of DH private exponent to generatetopic/pkey-dh-generate-key-length
Add an optional parameter to OpenSSL::PKey::DH#generate_key! that
specifies the size in bits of the private exponent to generate. OpenSSL
by default generates one with the maximum size: dh.p.num_bits-1. This is
usually unnecessarily too large. Let user choose by their needs.
-rw-r--r-- | ext/openssl/openssl_missing.h | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_dh.c | 20 | ||||
-rw-r--r-- | test/test_pkey_dh.rb | 7 |
3 files changed, 24 insertions, 5 deletions
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index cc31f6ac..ad7803dc 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -187,6 +187,8 @@ IMPL_PKEY_GETTER(DH, dh) IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || obj->q && q == obj->q || g == obj->g)) static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } +static inline long DH_get_length(const DH *dh) { return dh->length; } +static inline int DH_set_length(DH *dh, long length) { dh->length = length; return 1; } #endif #if !defined(OPENSSL_NO_EC) diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index dd85b7b9..de1dbf31 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -493,26 +493,36 @@ ossl_dh_check_params(VALUE self) /* * call-seq: - * dh.generate_key! -> self + * dh.generate_key! -> self + * dh.generate_key!(length) -> self * - * Generates a private and public key unless a private key already exists. + * Generates a new random private and public exponent pair. * If this DH instance was generated from public DH parameters (e.g. by * encoding the result of DH#public_key), then this method needs to be * called first in order to generate the per-session keys before performing * the actual key exchange. * + * If the optional parameter +length+ is given, a private exponent with that + * length (in bits) will be generated. This can be used to reduce calculation + * cost. + * * === Example * dh = OpenSSL::PKey::DH.new(2048) - * public_key = dh.public_key #contains no private/public key yet + * public_key = dh.public_key # contains no private/public key yet * public_key.generate_key! * puts public_key.private? # => true */ static VALUE -ossl_dh_generate_key(VALUE self) +ossl_dh_generate_key(int argc, VALUE *argv, VALUE self) { DH *dh; + VALUE len_v; + long len; + rb_scan_args(argc, argv, "01", &len_v); GetDH(self, dh); + len = NIL_P(len_v) ? 0 : NUM2LONG(len_v); + DH_set_length(dh, len); if (!DH_generate_key(dh)) ossl_raise(eDHError, "Failed to generate key"); return self; @@ -628,7 +638,7 @@ Init_ossl_dh(void) rb_define_method(cDH, "to_der", ossl_dh_to_der, 0); rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0); rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0); - rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0); + rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, -1); rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1); DEF_OSSL_PKEY_BN(cDH, dh, p); diff --git a/test/test_pkey_dh.rb b/test/test_pkey_dh.rb index 09a24279..bc6b722b 100644 --- a/test/test_pkey_dh.rb +++ b/test/test_pkey_dh.rb @@ -68,6 +68,13 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase assert_no_key(dh) dh.generate_key! assert_key(dh) + assert_equal(1024-1, dh.priv_key.num_bits) + + dh = Fixtures.pkey_dh("dh1024").public_key # creates a copy + assert_no_key(dh) + dh.generate_key!(320) + assert_key(dh) + assert_equal(320, dh.priv_key.num_bits) end def test_key_exchange |