[前][次][番号順一覧][スレッド一覧]

ruby-changes:70365

From: Kazuki <ko1@a...>
Date: Tue, 21 Dec 2021 00:11:23 +0900 (JST)
Subject: [ruby-changes:70365] 0d698be04f (master): [ruby/openssl] pkey/dh: deprecate OpenSSL::PKey::DH#generate_key!

https://git.ruby-lang.org/ruby.git/commit/?id=0d698be04f

From 0d698be04f6c76250706e8d56f542c3c7fca0fa7 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@r...>
Date: Fri, 22 Oct 2021 16:24:07 +0900
Subject: [ruby/openssl] pkey/dh: deprecate OpenSSL::PKey::DH#generate_key!

OpenSSL::PKey::DH#generate_key! will not work on OpenSSL 3.0 because
keys are made immutable. Users should use OpenSSL::PKey.generate_key
instead.

https://github.com/ruby/openssl/commit/8ee6a582c7
---
 ext/openssl/lib/openssl/pkey.rb | 23 +++++++++++++++++++----
 ext/openssl/ossl_pkey_dh.c      |  9 +++++----
 test/openssl/test_pkey_dh.rb    | 18 ++++++++++--------
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index ba04cf4b393..c3e06290910 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -71,14 +71,29 @@ module OpenSSL::PKey https://github.com/ruby/ruby/blob/trunk/ext/openssl/lib/openssl/pkey.rb#L71
     # called first in order to generate the per-session keys before performing
     # the actual key exchange.
     #
+    # <b>Deprecated in version 3.0</b>. This method is incompatible with
+    # OpenSSL 3.0.0 or later.
+    #
     # 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
+    #   # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later
+    #   dh0 = OpenSSL::PKey::DH.new(2048)
+    #   dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name)
+    #   dh.generate_key!
+    #   puts dh.private? # => true
+    #   puts dh0.pub_key == dh.pub_key #=> false
+    #
+    #   # With OpenSSL::PKey.generate_key
+    #   dh0 = OpenSSL::PKey::DH.new(2048)
+    #   dh = OpenSSL::PKey.generate_key(dh0)
+    #   puts dh0.pub_key == dh.pub_key #=> false
     def generate_key!
+      if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000
+        raise DHError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \
+        "use OpenSSL::PKey.generate_key instead"
+      end
+
       unless priv_key
         tmp = OpenSSL::PKey.generate_key(self)
         set_key(tmp.pub_key, tmp.priv_key)
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index d6f32c62f7a..696455dcfd3 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -58,15 +58,16 @@ VALUE eDHError; https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_dh.c#L58
  *
  * Examples:
  *   # Creating an instance from scratch
- *   dh = DH.new
+ *   # Note that this is deprecated and will not work on OpenSSL 3.0 or later.
+ *   dh = OpenSSL::PKey::DH.new
  *   dh.set_pqg(bn_p, nil, bn_g)
  *
  *   # Generating a parameters and a key pair
- *   dh = DH.new(2048) # An alias of DH.generate(2048)
+ *   dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048)
  *
  *   # Reading DH parameters
- *   dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
- *   dh.generate_key! # -> dh with public and private key
+ *   dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only
+ *   dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair
  */
 static VALUE
 ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 757704caf67..ac11af382a7 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -26,14 +26,19 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_pkey_dh.rb#L26
   end
 
   def test_derive_key
-    dh1 = Fixtures.pkey("dh1024").generate_key!
-    dh2 = Fixtures.pkey("dh1024").generate_key!
+    params = Fixtures.pkey("dh1024")
+    dh1 = OpenSSL::PKey.generate_key(params)
+    dh2 = OpenSSL::PKey.generate_key(params)
     dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
     dh2_pub = OpenSSL::PKey.read(dh2.public_to_der)
+
     z = dh1.g.mod_exp(dh1.priv_key, dh1.p).mod_exp(dh2.priv_key, dh1.p).to_s(2)
     assert_equal z, dh1.derive(dh2_pub)
     assert_equal z, dh2.derive(dh1_pub)
 
+    assert_raise(OpenSSL::PKey::PKeyError) { params.derive(dh1_pub) }
+    assert_raise(OpenSSL::PKey::PKeyError) { dh1_pub.derive(params) }
+
     assert_equal z, dh1.compute_key(dh2.pub_key)
     assert_equal z, dh2.compute_key(dh1.pub_key)
   end
@@ -74,19 +79,16 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_pkey_dh.rb#L79
   end
 
   def test_generate_key
-    dh = Fixtures.pkey("dh1024").public_key # creates a copy
+    # Deprecated in v3.0.0; incompatible with OpenSSL 3.0
+    dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only
     assert_no_key(dh)
     dh.generate_key!
     assert_key(dh)
-  end
 
-  def test_key_exchange
-    dh = Fixtures.pkey("dh1024")
     dh2 = dh.public_key
-    dh.generate_key!
     dh2.generate_key!
     assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
-  end
+  end if !openssl?(3, 0, 0)
 
   def test_params_ok?
     dh0 = Fixtures.pkey("dh1024")
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]