summaryrefslogtreecommitdiff
path: root/ext/openssl/lib/openssl/pkey.rb
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2020-05-17 20:48:23 +0900
committerKazuki Yamaguchi <k@rhe.jp>2021-07-18 17:44:47 +0900
commit098985a5e66e4dd6b01d246909b66d3d7e4024c0 (patch)
treef0afa592ec0f525787c512090b08c277b28f60fd /ext/openssl/lib/openssl/pkey.rb
parent595644e4f65f35e35f4c81e3aa228ac7d7f091d4 (diff)
[ruby/openssl] pkey/dh: use high level EVP interface to generate parameters and keys
Implement PKey::DH.new(size, gen), PKey::DH.generate(size, gen), and PKey::DH#generate_key! using PKey.generate_parameters and .generate_key instead of the low level DH functions. Note that the EVP interface can enforce additional restrictions - for example, DH key shorter than 2048 bits is no longer accepted by default in OpenSSL 3.0. The test code is updated accordingly. https://github.com/ruby/openssl/commit/c2e9b16f0b
Diffstat (limited to 'ext/openssl/lib/openssl/pkey.rb')
-rw-r--r--ext/openssl/lib/openssl/pkey.rb57
1 files changed, 57 insertions, 0 deletions
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index be60ac2beb..5a3d0ed1ef 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -27,6 +27,63 @@ module OpenSSL::PKey
peer.set_key(pub_bn, nil)
derive(peer)
end
+
+ # :call-seq:
+ # dh.generate_key! -> self
+ #
+ # Generates a private and public key unless a private key already exists.
+ # 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.
+ #
+ # See also OpenSSL::PKey.generate_key.
+ #
+ # Example:
+ # dh = OpenSSL::PKey::DH.new(2048)
+ # public_key = dh.public_key #contains no private/public key yet
+ # public_key.generate_key!
+ # puts public_key.private? # => true
+ def generate_key!
+ unless priv_key
+ tmp = OpenSSL::PKey.generate_key(self)
+ set_key(tmp.pub_key, tmp.priv_key)
+ end
+ self
+ end
+
+ class << self
+ # :call-seq:
+ # DH.generate(size, generator = 2) -> dh
+ #
+ # Creates a new DH instance from scratch by generating random parameters
+ # and a key pair.
+ #
+ # See also OpenSSL::PKey.generate_parameters and
+ # OpenSSL::PKey.generate_key.
+ #
+ # +size+::
+ # The desired key size in bits.
+ # +generator+::
+ # The generator.
+ def generate(size, generator = 2, &blk)
+ dhparams = OpenSSL::PKey.generate_parameters("DH", {
+ "dh_paramgen_prime_len" => size,
+ "dh_paramgen_generator" => generator,
+ }, &blk)
+ OpenSSL::PKey.generate_key(dhparams)
+ end
+
+ # Handle DH.new(size, generator) form here; new(str) and new() forms
+ # are handled by #initialize
+ def new(*args, &blk) # :nodoc:
+ if args[0].is_a?(Integer)
+ generate(*args, &blk)
+ else
+ super
+ end
+ end
+ end
end
class DSA