6daba0
From e8504c6248c4b0e5e961f57f004e1133c20c88a5 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Mon, 5 Apr 2021 00:30:01 +0900
6daba0
Subject: [PATCH 1/5] pkey: fix interrupt handling in
6daba0
 OpenSSL::PKey.generate_key
6daba0
6daba0
rb_thread_call_without_gvl() can be interrupted, but it may be able to
6daba0
resume the operation. Call rb_thread_check_ints() to see if it raises
6daba0
an exception or not.
6daba0
---
6daba0
 ext/openssl/ossl_pkey.c | 18 +++++++++++++-----
6daba0
 1 file changed, 13 insertions(+), 5 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
6daba0
index 22e9f19982..d76f0600d1 100644
6daba0
--- a/ext/openssl/ossl_pkey.c
6daba0
+++ b/ext/openssl/ossl_pkey.c
6daba0
@@ -239,7 +239,7 @@ struct pkey_blocking_generate_arg {
6daba0
     int state;
6daba0
     int yield: 1;
6daba0
     int genparam: 1;
6daba0
-    int stop: 1;
6daba0
+    int interrupted: 1;
6daba0
 };
6daba0
 
6daba0
 static VALUE
6daba0
@@ -261,23 +261,31 @@ static int
6daba0
 pkey_gen_cb(EVP_PKEY_CTX *ctx)
6daba0
 {
6daba0
     struct pkey_blocking_generate_arg *arg = EVP_PKEY_CTX_get_app_data(ctx);
6daba0
+    int state;
6daba0
 
6daba0
     if (arg->yield) {
6daba0
-        int state;
6daba0
         rb_protect(pkey_gen_cb_yield, (VALUE)ctx, &state);
6daba0
         if (state) {
6daba0
-            arg->stop = 1;
6daba0
             arg->state = state;
6daba0
+            return 0;
6daba0
+        }
6daba0
+    }
6daba0
+    if (arg->interrupted) {
6daba0
+        arg->interrupted = 0;
6daba0
+        state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
6daba0
+        if (state) {
6daba0
+            arg->state = state;
6daba0
+            return 0;
6daba0
         }
6daba0
     }
6daba0
-    return !arg->stop;
6daba0
+    return 1;
6daba0
 }
6daba0
 
6daba0
 static void
6daba0
 pkey_blocking_gen_stop(void *ptr)
6daba0
 {
6daba0
     struct pkey_blocking_generate_arg *arg = ptr;
6daba0
-    arg->stop = 1;
6daba0
+    arg->interrupted = 1;
6daba0
 }
6daba0
 
6daba0
 static void *
6daba0
-- 
6daba0
2.32.0
6daba0
6daba0
6daba0
From f433d1b680e7ac5ef13fc15b0844267222438cf3 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sun, 17 May 2020 20:48:23 +0900
6daba0
Subject: [PATCH 2/5] pkey/dh: use high level EVP interface to generate
6daba0
 parameters and keys
6daba0
6daba0
Implement PKey::DH.new(size, gen), PKey::DH.generate(size, gen), and
6daba0
PKey::DH#generate_key! using PKey.generate_parameters and .generate_key
6daba0
instead of the low level DH functions.
6daba0
6daba0
Note that the EVP interface can enforce additional restrictions - for
6daba0
example, DH key shorter than 2048 bits is no longer accepted by default
6daba0
in OpenSSL 3.0. The test code is updated accordingly.
6daba0
---
6daba0
 ext/openssl/lib/openssl/pkey.rb |  57 ++++++++++
6daba0
 ext/openssl/ossl_pkey_dh.c      | 186 ++++++--------------------------
6daba0
 test/openssl/test_pkey_dh.rb    |  15 ++-
6daba0
 3 files changed, 101 insertions(+), 157 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
6daba0
index be60ac2beb..5a3d0ed1ef 100644
6daba0
--- a/ext/openssl/lib/openssl/pkey.rb
6daba0
+++ b/ext/openssl/lib/openssl/pkey.rb
6daba0
@@ -27,6 +27,63 @@ def compute_key(pub_bn)
6daba0
       peer.set_key(pub_bn, nil)
6daba0
       derive(peer)
6daba0
     end
6daba0
+
6daba0
+    # :call-seq:
6daba0
+    #    dh.generate_key! -> self
6daba0
+    #
6daba0
+    # Generates a private and public key unless a private key already exists.
6daba0
+    # If this DH instance was generated from public \DH parameters (e.g. by
6daba0
+    # encoding the result of DH#public_key), then this method needs to be
6daba0
+    # called first in order to generate the per-session keys before performing
6daba0
+    # the actual key exchange.
6daba0
+    #
6daba0
+    # See also OpenSSL::PKey.generate_key.
6daba0
+    #
6daba0
+    # Example:
6daba0
+    #   dh = OpenSSL::PKey::DH.new(2048)
6daba0
+    #   public_key = dh.public_key #contains no private/public key yet
6daba0
+    #   public_key.generate_key!
6daba0
+    #   puts public_key.private? # => true
6daba0
+    def generate_key!
6daba0
+      unless priv_key
6daba0
+        tmp = OpenSSL::PKey.generate_key(self)
6daba0
+        set_key(tmp.pub_key, tmp.priv_key)
6daba0
+      end
6daba0
+      self
6daba0
+    end
6daba0
+
6daba0
+    class << self
6daba0
+      # :call-seq:
6daba0
+      #    DH.generate(size, generator = 2) -> dh
6daba0
+      #
6daba0
+      # Creates a new DH instance from scratch by generating random parameters
6daba0
+      # and a key pair.
6daba0
+      #
6daba0
+      # See also OpenSSL::PKey.generate_parameters and
6daba0
+      # OpenSSL::PKey.generate_key.
6daba0
+      #
6daba0
+      # +size+::
6daba0
+      #   The desired key size in bits.
6daba0
+      # +generator+::
6daba0
+      #   The generator.
6daba0
+      def generate(size, generator = 2, &blk)
6daba0
+        dhparams = OpenSSL::PKey.generate_parameters("DH", {
6daba0
+          "dh_paramgen_prime_len" => size,
6daba0
+          "dh_paramgen_generator" => generator,
6daba0
+        }, &blk)
6daba0
+        OpenSSL::PKey.generate_key(dhparams)
6daba0
+      end
6daba0
+
6daba0
+      # Handle DH.new(size, generator) form here; new(str) and new() forms
6daba0
+      # are handled by #initialize
6daba0
+      def new(*args, &blk) # :nodoc:
6daba0
+        if args[0].is_a?(Integer)
6daba0
+          generate(*args, &blk)
6daba0
+        else
6daba0
+          super
6daba0
+        end
6daba0
+      end
6daba0
+    end
6daba0
   end
6daba0
 
6daba0
   class DSA
6daba0
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
6daba0
index 5bc1c49ca1..6b477b077c 100644
6daba0
--- a/ext/openssl/ossl_pkey_dh.c
6daba0
+++ b/ext/openssl/ossl_pkey_dh.c
6daba0
@@ -32,147 +32,56 @@ VALUE eDHError;
6daba0
 /*
6daba0
  * Private
6daba0
  */
6daba0
-struct dh_blocking_gen_arg {
6daba0
-    DH *dh;
6daba0
-    int size;
6daba0
-    int gen;
6daba0
-    BN_GENCB *cb;
6daba0
-    int result;
6daba0
-};
6daba0
-
6daba0
-static void *
6daba0
-dh_blocking_gen(void *arg)
6daba0
-{
6daba0
-    struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg;
6daba0
-    gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
6daba0
-    return 0;
6daba0
-}
6daba0
-
6daba0
-static DH *
6daba0
-dh_generate(int size, int gen)
6daba0
-{
6daba0
-    struct ossl_generate_cb_arg cb_arg = { 0 };
6daba0
-    struct dh_blocking_gen_arg gen_arg;
6daba0
-    DH *dh = DH_new();
6daba0
-    BN_GENCB *cb = BN_GENCB_new();
6daba0
-
6daba0
-    if (!dh || !cb) {
6daba0
-	DH_free(dh);
6daba0
-	BN_GENCB_free(cb);
6daba0
-        ossl_raise(eDHError, "malloc failure");
6daba0
-    }
6daba0
-
6daba0
-    if (rb_block_given_p())
6daba0
-	cb_arg.yield = 1;
6daba0
-    BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
6daba0
-    gen_arg.dh = dh;
6daba0
-    gen_arg.size = size;
6daba0
-    gen_arg.gen = gen;
6daba0
-    gen_arg.cb = cb;
6daba0
-    if (cb_arg.yield == 1) {
6daba0
-	/* we cannot release GVL when callback proc is supplied */
6daba0
-	dh_blocking_gen(&gen_arg);
6daba0
-    } else {
6daba0
-	/* there's a chance to unblock */
6daba0
-	rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
6daba0
-    }
6daba0
-
6daba0
-    BN_GENCB_free(cb);
6daba0
-    if (!gen_arg.result) {
6daba0
-	DH_free(dh);
6daba0
-	if (cb_arg.state) {
6daba0
-	    /* Clear OpenSSL error queue before re-raising. */
6daba0
-	    ossl_clear_error();
6daba0
-	    rb_jump_tag(cb_arg.state);
6daba0
-	}
6daba0
-        ossl_raise(eDHError, "DH_generate_parameters_ex");
6daba0
-    }
6daba0
-
6daba0
-    if (!DH_generate_key(dh)) {
6daba0
-        DH_free(dh);
6daba0
-        ossl_raise(eDHError, "DH_generate_key");
6daba0
-    }
6daba0
-
6daba0
-    return dh;
6daba0
-}
6daba0
-
6daba0
-/*
6daba0
- *  call-seq:
6daba0
- *     DH.generate(size [, generator]) -> dh
6daba0
- *
6daba0
- * Creates a new DH instance from scratch by generating the private and public
6daba0
- * components alike.
6daba0
- *
6daba0
- * === Parameters
6daba0
- * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
6daba0
- * * _generator_ is a small number > 1, typically 2 or 5.
6daba0
- *
6daba0
- */
6daba0
-static VALUE
6daba0
-ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
6daba0
-{
6daba0
-    EVP_PKEY *pkey;
6daba0
-    DH *dh ;
6daba0
-    int g = 2;
6daba0
-    VALUE size, gen, obj;
6daba0
-
6daba0
-    if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
6daba0
-	g = NUM2INT(gen);
6daba0
-    }
6daba0
-    obj = rb_obj_alloc(klass);
6daba0
-    GetPKey(obj, pkey);
6daba0
-
6daba0
-    dh = dh_generate(NUM2INT(size), g);
6daba0
-    if (!EVP_PKEY_assign_DH(pkey, dh)) {
6daba0
-        DH_free(dh);
6daba0
-        ossl_raise(eDHError, "EVP_PKEY_assign_DH");
6daba0
-    }
6daba0
-    return obj;
6daba0
-}
6daba0
-
6daba0
 /*
6daba0
  * call-seq:
6daba0
  *   DH.new -> dh
6daba0
  *   DH.new(string) -> dh
6daba0
  *   DH.new(size [, generator]) -> dh
6daba0
  *
6daba0
- * Either generates a DH instance from scratch or by reading already existing
6daba0
- * DH parameters from _string_. Note that when reading a DH instance from
6daba0
- * data that was encoded from a DH instance by using DH#to_pem or DH#to_der
6daba0
- * the result will *not* contain a public/private key pair yet. This needs to
6daba0
- * be generated using DH#generate_key! first.
6daba0
+ * Creates a new instance of OpenSSL::PKey::DH.
6daba0
+ *
6daba0
+ * If called without arguments, an empty instance without any parameter or key
6daba0
+ * components is created. Use #set_pqg to manually set the parameters afterwards
6daba0
+ * (and optionally #set_key to set private and public key components).
6daba0
+ *
6daba0
+ * If a String is given, tries to parse it as a DER- or PEM- encoded parameters.
6daba0
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
6daba0
+ *
6daba0
+ * The DH.new(size [, generator]) form is an alias of DH.generate.
6daba0
  *
6daba0
- * === Parameters
6daba0
- * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
6daba0
- * * _generator_ is a small number > 1, typically 2 or 5.
6daba0
- * * _string_ contains the DER or PEM encoded key.
6daba0
+ * +string+::
6daba0
+ *   A String that contains the DER or PEM encoded key.
6daba0
+ * +size+::
6daba0
+ *   See DH.generate.
6daba0
+ * +generator+::
6daba0
+ *   See DH.generate.
6daba0
  *
6daba0
- * === Examples
6daba0
- *  DH.new # -> dh
6daba0
- *  DH.new(1024) # -> dh
6daba0
- *  DH.new(1024, 5) # -> dh
6daba0
- *  #Reading DH parameters
6daba0
- *  dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
6daba0
- *  dh.generate_key! # -> dh with public and private key
6daba0
+ * Examples:
6daba0
+ *   # Creating an instance from scratch
6daba0
+ *   dh = DH.new
6daba0
+ *   dh.set_pqg(bn_p, nil, bn_g)
6daba0
+ *
6daba0
+ *   # Generating a parameters and a key pair
6daba0
+ *   dh = DH.new(2048) # An alias of DH.generate(2048)
6daba0
+ *
6daba0
+ *   # Reading DH parameters
6daba0
+ *   dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
6daba0
+ *   dh.generate_key! # -> dh with public and private key
6daba0
  */
6daba0
 static VALUE
6daba0
 ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
6daba0
 {
6daba0
     EVP_PKEY *pkey;
6daba0
     DH *dh;
6daba0
-    int g = 2;
6daba0
     BIO *in;
6daba0
-    VALUE arg, gen;
6daba0
+    VALUE arg;
6daba0
 
6daba0
     GetPKey(self, pkey);
6daba0
-    if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) {
6daba0
-      dh = DH_new();
6daba0
-    }
6daba0
-    else if (RB_INTEGER_TYPE_P(arg)) {
6daba0
-	if (!NIL_P(gen)) {
6daba0
-	    g = NUM2INT(gen);
6daba0
-	}
6daba0
-        dh = dh_generate(NUM2INT(arg), g);
6daba0
+    /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */
6daba0
+    if (rb_scan_args(argc, argv, "01", &arg) == 0) {
6daba0
+        dh = DH_new();
6daba0
+        if (!dh)
6daba0
+            ossl_raise(eDHError, "DH_new");
6daba0
     }
6daba0
     else {
6daba0
 	arg = ossl_to_der_if_possible(arg);
6daba0
@@ -449,33 +358,6 @@ ossl_dh_check_params(VALUE self)
6daba0
     return codes == 0 ? Qtrue : Qfalse;
6daba0
 }
6daba0
 
6daba0
-/*
6daba0
- *  call-seq:
6daba0
- *     dh.generate_key! -> self
6daba0
- *
6daba0
- * Generates a private and public key unless a private key already exists.
6daba0
- * If this DH instance was generated from public DH parameters (e.g. by
6daba0
- * encoding the result of DH#public_key), then this method needs to be
6daba0
- * called first in order to generate the per-session keys before performing
6daba0
- * the actual key exchange.
6daba0
- *
6daba0
- * === Example
6daba0
- *   dh = OpenSSL::PKey::DH.new(2048)
6daba0
- *   public_key = dh.public_key #contains no private/public key yet
6daba0
- *   public_key.generate_key!
6daba0
- *   puts public_key.private? # => true
6daba0
- */
6daba0
-static VALUE
6daba0
-ossl_dh_generate_key(VALUE self)
6daba0
-{
6daba0
-    DH *dh;
6daba0
-
6daba0
-    GetDH(self, dh);
6daba0
-    if (!DH_generate_key(dh))
6daba0
-	ossl_raise(eDHError, "Failed to generate key");
6daba0
-    return self;
6daba0
-}
6daba0
-
6daba0
 /*
6daba0
  * Document-method: OpenSSL::PKey::DH#set_pqg
6daba0
  * call-seq:
6daba0
@@ -540,7 +422,6 @@ Init_ossl_dh(void)
6daba0
      *  puts symm_key1 == symm_key2 # => true
6daba0
      */
6daba0
     cDH = rb_define_class_under(mPKey, "DH", cPKey);
6daba0
-    rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
6daba0
     rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
6daba0
     rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
6daba0
     rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
6daba0
@@ -552,7 +433,6 @@ Init_ossl_dh(void)
6daba0
     rb_define_method(cDH, "to_der", ossl_dh_to_der, 0);
6daba0
     rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0);
6daba0
     rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0);
6daba0
-    rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0);
6daba0
 
6daba0
     DEF_OSSL_PKEY_BN(cDH, dh, p);
6daba0
     DEF_OSSL_PKEY_BN(cDH, dh, q);
6daba0
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
6daba0
index 9efc3ba68d..279ce1984c 100644
6daba0
--- a/test/openssl/test_pkey_dh.rb
6daba0
+++ b/test/openssl/test_pkey_dh.rb
6daba0
@@ -4,12 +4,19 @@
6daba0
 if defined?(OpenSSL) && defined?(OpenSSL::PKey::DH)
6daba0
 
6daba0
 class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
6daba0
-  NEW_KEYLEN = 256
6daba0
+  NEW_KEYLEN = 2048
6daba0
 
6daba0
-  def test_new
6daba0
+  def test_new_empty
6daba0
+    dh = OpenSSL::PKey::DH.new
6daba0
+    assert_equal nil, dh.p
6daba0
+    assert_equal nil, dh.priv_key
6daba0
+  end
6daba0
+
6daba0
+  def test_new_generate
6daba0
+    # This test is slow
6daba0
     dh = OpenSSL::PKey::DH.new(NEW_KEYLEN)
6daba0
     assert_key(dh)
6daba0
-  end
6daba0
+  end if ENV["OSSL_TEST_ALL"]
6daba0
 
6daba0
   def test_new_break
6daba0
     assert_nil(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break })
6daba0
@@ -80,7 +87,7 @@ def test_key_exchange
6daba0
   end
6daba0
 
6daba0
   def test_dup
6daba0
-    dh = OpenSSL::PKey::DH.new(NEW_KEYLEN)
6daba0
+    dh = Fixtures.pkey("dh1024")
6daba0
     dh2 = dh.dup
6daba0
     assert_equal dh.to_der, dh2.to_der # params
6daba0
     assert_equal_params dh, dh2 # keys
6daba0
-- 
6daba0
2.32.0
6daba0
6daba0
6daba0
From ba1d1d68ac2b489691eb3fe2052e77b3e57a372b Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sun, 17 May 2020 20:48:23 +0900
6daba0
Subject: [PATCH 3/5] pkey/rsa: use high level EVP interface to generate
6daba0
 parameters and keys
6daba0
6daba0
Implement PKey::RSA.new(size, exponent) and PKey::RSA.generate using
6daba0
OpenSSL::PKey.generate_key instead of the low level RSA functions.
6daba0
---
6daba0
 ext/openssl/lib/openssl/pkey.rb |  30 ++++++++
6daba0
 ext/openssl/ossl_pkey_rsa.c     | 132 ++++----------------------------
6daba0
 2 files changed, 46 insertions(+), 116 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
6daba0
index 5a3d0ed1ef..3bef06e3b3 100644
6daba0
--- a/ext/openssl/lib/openssl/pkey.rb
6daba0
+++ b/ext/openssl/lib/openssl/pkey.rb
6daba0
@@ -128,5 +128,35 @@ def to_bn(conversion_form = group.point_conversion_form)
6daba0
 
6daba0
   class RSA
6daba0
     include OpenSSL::Marshal
6daba0
+
6daba0
+    class << self
6daba0
+      # :call-seq:
6daba0
+      #    RSA.generate(size, exponent = 65537) -> RSA
6daba0
+      #
6daba0
+      # Generates an \RSA keypair.
6daba0
+      #
6daba0
+      # See also OpenSSL::PKey.generate_key.
6daba0
+      #
6daba0
+      # +size+::
6daba0
+      #   The desired key size in bits.
6daba0
+      # +exponent+::
6daba0
+      #   An odd Integer, normally 3, 17, or 65537.
6daba0
+      def generate(size, exp = 0x10001, &blk)
6daba0
+        OpenSSL::PKey.generate_key("RSA", {
6daba0
+          "rsa_keygen_bits" => size,
6daba0
+          "rsa_keygen_pubexp" => exp,
6daba0
+        }, &blk)
6daba0
+      end
6daba0
+
6daba0
+      # Handle RSA.new(size, exponent) form here; new(str) and new() forms
6daba0
+      # are handled by #initialize
6daba0
+      def new(*args, &blk) # :nodoc:
6daba0
+        if args[0].is_a?(Integer)
6daba0
+          generate(*args, &blk)
6daba0
+        else
6daba0
+          super
6daba0
+        end
6daba0
+      end
6daba0
+    end
6daba0
   end
6daba0
 end
6daba0
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
6daba0
index 3c298a2aea..43f82cb29e 100644
6daba0
--- a/ext/openssl/ossl_pkey_rsa.c
6daba0
+++ b/ext/openssl/ossl_pkey_rsa.c
6daba0
@@ -47,125 +47,28 @@ VALUE eRSAError;
6daba0
 /*
6daba0
  * Private
6daba0
  */
6daba0
-struct rsa_blocking_gen_arg {
6daba0
-    RSA *rsa;
6daba0
-    BIGNUM *e;
6daba0
-    int size;
6daba0
-    BN_GENCB *cb;
6daba0
-    int result;
6daba0
-};
6daba0
-
6daba0
-static void *
6daba0
-rsa_blocking_gen(void *arg)
6daba0
-{
6daba0
-    struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg;
6daba0
-    gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb);
6daba0
-    return 0;
6daba0
-}
6daba0
-
6daba0
-static RSA *
6daba0
-rsa_generate(int size, unsigned long exp)
6daba0
-{
6daba0
-    int i;
6daba0
-    struct ossl_generate_cb_arg cb_arg = { 0 };
6daba0
-    struct rsa_blocking_gen_arg gen_arg;
6daba0
-    RSA *rsa = RSA_new();
6daba0
-    BIGNUM *e = BN_new();
6daba0
-    BN_GENCB *cb = BN_GENCB_new();
6daba0
-
6daba0
-    if (!rsa || !e || !cb) {
6daba0
-	RSA_free(rsa);
6daba0
-	BN_free(e);
6daba0
-	BN_GENCB_free(cb);
6daba0
-        ossl_raise(eRSAError, "malloc failure");
6daba0
-    }
6daba0
-    for (i = 0; i < (int)sizeof(exp) * 8; ++i) {
6daba0
-	if (exp & (1UL << i)) {
6daba0
-	    if (BN_set_bit(e, i) == 0) {
6daba0
-		BN_free(e);
6daba0
-		RSA_free(rsa);
6daba0
-		BN_GENCB_free(cb);
6daba0
-                ossl_raise(eRSAError, "BN_set_bit");
6daba0
-	    }
6daba0
-	}
6daba0
-    }
6daba0
-
6daba0
-    if (rb_block_given_p())
6daba0
-	cb_arg.yield = 1;
6daba0
-    BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
6daba0
-    gen_arg.rsa = rsa;
6daba0
-    gen_arg.e = e;
6daba0
-    gen_arg.size = size;
6daba0
-    gen_arg.cb = cb;
6daba0
-    if (cb_arg.yield == 1) {
6daba0
-	/* we cannot release GVL when callback proc is supplied */
6daba0
-	rsa_blocking_gen(&gen_arg);
6daba0
-    } else {
6daba0
-	/* there's a chance to unblock */
6daba0
-	rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
6daba0
-    }
6daba0
-
6daba0
-    BN_GENCB_free(cb);
6daba0
-    BN_free(e);
6daba0
-    if (!gen_arg.result) {
6daba0
-	RSA_free(rsa);
6daba0
-	if (cb_arg.state) {
6daba0
-	    /* must clear OpenSSL error stack */
6daba0
-	    ossl_clear_error();
6daba0
-	    rb_jump_tag(cb_arg.state);
6daba0
-	}
6daba0
-        ossl_raise(eRSAError, "RSA_generate_key_ex");
6daba0
-    }
6daba0
-
6daba0
-    return rsa;
6daba0
-}
6daba0
-
6daba0
 /*
6daba0
  * call-seq:
6daba0
- *   RSA.generate(size)           => RSA instance
6daba0
- *   RSA.generate(size, exponent) => RSA instance
6daba0
+ *   RSA.new -> rsa
6daba0
+ *   RSA.new(encoded_key [, passphrase]) -> rsa
6daba0
+ *   RSA.new(encoded_key) { passphrase } -> rsa
6daba0
+ *   RSA.new(size [, exponent]) -> rsa
6daba0
  *
6daba0
- * Generates an RSA keypair.  _size_ is an integer representing the desired key
6daba0
- * size.  Keys smaller than 1024 should be considered insecure.  _exponent_ is
6daba0
- * an odd number normally 3, 17, or 65537.
6daba0
- */
6daba0
-static VALUE
6daba0
-ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
6daba0
-{
6daba0
-/* why does this method exist?  why can't initialize take an optional exponent? */
6daba0
-    EVP_PKEY *pkey;
6daba0
-    RSA *rsa;
6daba0
-    VALUE size, exp;
6daba0
-    VALUE obj;
6daba0
-
6daba0
-    rb_scan_args(argc, argv, "11", &size, &exp);
6daba0
-    obj = rb_obj_alloc(klass);
6daba0
-    GetPKey(obj, pkey);
6daba0
-
6daba0
-    rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp));
6daba0
-    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
6daba0
-        RSA_free(rsa);
6daba0
-        ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
6daba0
-    }
6daba0
-    return obj;
6daba0
-}
6daba0
-
6daba0
-/*
6daba0
- * call-seq:
6daba0
- *   RSA.new(size [, exponent])        => RSA instance
6daba0
- *   RSA.new(encoded_key)              => RSA instance
6daba0
- *   RSA.new(encoded_key, pass_phrase) => RSA instance
6daba0
+ * Generates or loads an \RSA keypair.
6daba0
  *
6daba0
- * Generates or loads an RSA keypair.  If an integer _key_size_ is given it
6daba0
- * represents the desired key size.  Keys less than 1024 bits should be
6daba0
- * considered insecure.
6daba0
+ * If called without arguments, creates a new instance with no key components
6daba0
+ * set. They can be set individually by #set_key, #set_factors, and
6daba0
+ * #set_crt_params.
6daba0
  *
6daba0
- * A key can instead be loaded from an _encoded_key_ which must be PEM or DER
6daba0
- * encoded.  A _pass_phrase_ can be used to decrypt the key.  If none is given
6daba0
- * OpenSSL will prompt for the pass phrase.
6daba0
+ * If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
6daba0
+ * Note that, if _passphrase_ is not specified but the key is encrypted with a
6daba0
+ * passphrase, \OpenSSL will prompt for it.
6daba0
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
6daba0
  *
6daba0
- * = Examples
6daba0
+ * If called with a number, generates a new key pair. This form works as an
6daba0
+ * alias of RSA.generate.
6daba0
  *
6daba0
+ * Examples:
6daba0
  *   OpenSSL::PKey::RSA.new 2048
6daba0
  *   OpenSSL::PKey::RSA.new File.read 'rsa.pem'
6daba0
  *   OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
6daba0
@@ -179,15 +82,13 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
6daba0
     VALUE arg, pass;
6daba0
 
6daba0
     GetPKey(self, pkey);
6daba0
+    /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
6daba0
     rb_scan_args(argc, argv, "02", &arg, &pass);
6daba0
     if (argc == 0) {
6daba0
 	rsa = RSA_new();
6daba0
         if (!rsa)
6daba0
             ossl_raise(eRSAError, "RSA_new");
6daba0
     }
6daba0
-    else if (RB_INTEGER_TYPE_P(arg)) {
6daba0
-	rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass));
6daba0
-    }
6daba0
     else {
6daba0
 	pass = ossl_pem_passwd_value(pass);
6daba0
 	arg = ossl_to_der_if_possible(arg);
6daba0
@@ -832,7 +733,6 @@ Init_ossl_rsa(void)
6daba0
      */
6daba0
     cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
6daba0
 
6daba0
-    rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
6daba0
     rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
6daba0
     rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
6daba0
 
6daba0
-- 
6daba0
2.32.0
6daba0
6daba0
6daba0
From a6c4a8116c09243c39cc8d1e7ececcd8be0cfaf2 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sun, 17 May 2020 22:14:03 +0900
6daba0
Subject: [PATCH 4/5] pkey/dsa: use high level EVP interface to generate
6daba0
 parameters and keys
6daba0
6daba0
Implement PKey::DSA.new(size) and PKey::DSA.generate using
6daba0
OpenSSL::PKey.generate_parameters and .generate_key instead of the low
6daba0
level DSA functions.
6daba0
---
6daba0
 ext/openssl/lib/openssl/pkey.rb |  30 +++++++
6daba0
 ext/openssl/ossl_pkey_dsa.c     | 140 ++++++--------------------------
6daba0
 test/openssl/test_pkey_dsa.rb   |  23 ++----
6daba0
 3 files changed, 64 insertions(+), 129 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
6daba0
index 3bef06e3b3..53ee52f98b 100644
6daba0
--- a/ext/openssl/lib/openssl/pkey.rb
6daba0
+++ b/ext/openssl/lib/openssl/pkey.rb
6daba0
@@ -88,6 +88,36 @@ def new(*args, &blk) # :nodoc:
6daba0
 
6daba0
   class DSA
6daba0
     include OpenSSL::Marshal
6daba0
+
6daba0
+    class << self
6daba0
+      # :call-seq:
6daba0
+      #    DSA.generate(size) -> dsa
6daba0
+      #
6daba0
+      # Creates a new DSA instance by generating a private/public key pair
6daba0
+      # from scratch.
6daba0
+      #
6daba0
+      # See also OpenSSL::PKey.generate_parameters and
6daba0
+      # OpenSSL::PKey.generate_key.
6daba0
+      #
6daba0
+      # +size+::
6daba0
+      #   The desired key size in bits.
6daba0
+      def generate(size, &blk)
6daba0
+        dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
6daba0
+          "dsa_paramgen_bits" => size,
6daba0
+        }, &blk)
6daba0
+        OpenSSL::PKey.generate_key(dsaparams)
6daba0
+      end
6daba0
+
6daba0
+      # Handle DSA.new(size) form here; new(str) and new() forms
6daba0
+      # are handled by #initialize
6daba0
+      def new(*args, &blk) # :nodoc:
6daba0
+        if args[0].is_a?(Integer)
6daba0
+          generate(*args, &blk)
6daba0
+        else
6daba0
+          super
6daba0
+        end
6daba0
+      end
6daba0
+    end
6daba0
   end
6daba0
 
6daba0
   if defined?(EC)
6daba0
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
6daba0
index 0e68f7f27f..1c5a8a737e 100644
6daba0
--- a/ext/openssl/ossl_pkey_dsa.c
6daba0
+++ b/ext/openssl/ossl_pkey_dsa.c
6daba0
@@ -46,126 +46,39 @@ VALUE eDSAError;
6daba0
 /*
6daba0
  * Private
6daba0
  */
6daba0
-struct dsa_blocking_gen_arg {
6daba0
-    DSA *dsa;
6daba0
-    int size;
6daba0
-    int *counter;
6daba0
-    unsigned long *h;
6daba0
-    BN_GENCB *cb;
6daba0
-    int result;
6daba0
-};
6daba0
-
6daba0
-static void *
6daba0
-dsa_blocking_gen(void *arg)
6daba0
-{
6daba0
-    struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg;
6daba0
-    gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, NULL, 0,
6daba0
-					     gen->counter, gen->h, gen->cb);
6daba0
-    return 0;
6daba0
-}
6daba0
-
6daba0
-static DSA *
6daba0
-dsa_generate(int size)
6daba0
-{
6daba0
-    struct ossl_generate_cb_arg cb_arg = { 0 };
6daba0
-    struct dsa_blocking_gen_arg gen_arg;
6daba0
-    DSA *dsa = DSA_new();
6daba0
-    BN_GENCB *cb = BN_GENCB_new();
6daba0
-    int counter;
6daba0
-    unsigned long h;
6daba0
-
6daba0
-    if (!dsa || !cb) {
6daba0
-        DSA_free(dsa);
6daba0
-        BN_GENCB_free(cb);
6daba0
-        ossl_raise(eDSAError, "malloc failure");
6daba0
-    }
6daba0
-
6daba0
-    if (rb_block_given_p())
6daba0
-	cb_arg.yield = 1;
6daba0
-    BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
6daba0
-    gen_arg.dsa = dsa;
6daba0
-    gen_arg.size = size;
6daba0
-    gen_arg.counter = &counter;
6daba0
-    gen_arg.h = &h;
6daba0
-    gen_arg.cb = cb;
6daba0
-    if (cb_arg.yield == 1) {
6daba0
-	/* we cannot release GVL when callback proc is supplied */
6daba0
-	dsa_blocking_gen(&gen_arg);
6daba0
-    } else {
6daba0
-	/* there's a chance to unblock */
6daba0
-	rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
6daba0
-    }
6daba0
-
6daba0
-    BN_GENCB_free(cb);
6daba0
-    if (!gen_arg.result) {
6daba0
-	DSA_free(dsa);
6daba0
-	if (cb_arg.state) {
6daba0
-	    /* Clear OpenSSL error queue before re-raising. By the way, the
6daba0
-	     * documentation of DSA_generate_parameters_ex() says the error code
6daba0
-	     * can be obtained by ERR_get_error(), but the default
6daba0
-	     * implementation, dsa_builtin_paramgen() doesn't put any error... */
6daba0
-	    ossl_clear_error();
6daba0
-	    rb_jump_tag(cb_arg.state);
6daba0
-	}
6daba0
-        ossl_raise(eDSAError, "DSA_generate_parameters_ex");
6daba0
-    }
6daba0
-
6daba0
-    if (!DSA_generate_key(dsa)) {
6daba0
-        DSA_free(dsa);
6daba0
-        ossl_raise(eDSAError, "DSA_generate_key");
6daba0
-    }
6daba0
-
6daba0
-    return dsa;
6daba0
-}
6daba0
-
6daba0
-/*
6daba0
- *  call-seq:
6daba0
- *    DSA.generate(size) -> dsa
6daba0
- *
6daba0
- * Creates a new DSA instance by generating a private/public key pair
6daba0
- * from scratch.
6daba0
- *
6daba0
- * === Parameters
6daba0
- * * _size_ is an integer representing the desired key size.
6daba0
- *
6daba0
- */
6daba0
-static VALUE
6daba0
-ossl_dsa_s_generate(VALUE klass, VALUE size)
6daba0
-{
6daba0
-    EVP_PKEY *pkey;
6daba0
-    DSA *dsa;
6daba0
-    VALUE obj;
6daba0
-
6daba0
-    obj = rb_obj_alloc(klass);
6daba0
-    GetPKey(obj, pkey);
6daba0
-
6daba0
-    dsa = dsa_generate(NUM2INT(size));
6daba0
-    if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
6daba0
-        DSA_free(dsa);
6daba0
-        ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
6daba0
-    }
6daba0
-    return obj;
6daba0
-}
6daba0
-
6daba0
 /*
6daba0
  *  call-seq:
6daba0
  *    DSA.new -> dsa
6daba0
- *    DSA.new(size) -> dsa
6daba0
  *    DSA.new(string [, pass]) -> dsa
6daba0
+ *    DSA.new(size) -> dsa
6daba0
  *
6daba0
  * Creates a new DSA instance by reading an existing key from _string_.
6daba0
  *
6daba0
- * === Parameters
6daba0
- * * _size_ is an integer representing the desired key size.
6daba0
- * * _string_ contains a DER or PEM encoded key.
6daba0
- * * _pass_ is a string that contains an optional password.
6daba0
+ * If called without arguments, creates a new instance with no key components
6daba0
+ * set. They can be set individually by #set_pqg and #set_key.
6daba0
  *
6daba0
- * === Examples
6daba0
- *  DSA.new -> dsa
6daba0
- *  DSA.new(1024) -> dsa
6daba0
- *  DSA.new(File.read('dsa.pem')) -> dsa
6daba0
- *  DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa
6daba0
+ * If called with a String, tries to parse as DER or PEM encoding of a \DSA key.
6daba0
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
6daba0
+ *
6daba0
+ * If called with a number, generates random parameters and a key pair. This
6daba0
+ * form works as an alias of DSA.generate.
6daba0
+ *
6daba0
+ * +string+::
6daba0
+ *   A String that contains a DER or PEM encoded key.
6daba0
+ * +pass+::
6daba0
+ *   A String that contains an optional password.
6daba0
+ * +size+::
6daba0
+ *   See DSA.generate.
6daba0
  *
6daba0
+ * Examples:
6daba0
+ *   p OpenSSL::PKey::DSA.new(1024)
6daba0
+ *   #=> #<OpenSSL::PKey::DSA:0x000055a8d6025bf0 oid=DSA>
6daba0
+ *
6daba0
+ *   p OpenSSL::PKey::DSA.new(File.read('dsa.pem'))
6daba0
+ *   #=> #<OpenSSL::PKey::DSA:0x000055555d6b8110 oid=DSA>
6daba0
+ *
6daba0
+ *   p OpenSSL::PKey::DSA.new(File.read('dsa.pem'), 'mypassword')
6daba0
+ *   #=> #<OpenSSL::PKey::DSA:0x0000556f973c40b8 oid=DSA>
6daba0
  */
6daba0
 static VALUE
6daba0
 ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
6daba0
@@ -176,15 +89,13 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
6daba0
     VALUE arg, pass;
6daba0
 
6daba0
     GetPKey(self, pkey);
6daba0
+    /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
6daba0
     rb_scan_args(argc, argv, "02", &arg, &pass);
6daba0
     if (argc == 0) {
6daba0
         dsa = DSA_new();
6daba0
         if (!dsa)
6daba0
             ossl_raise(eDSAError, "DSA_new");
6daba0
     }
6daba0
-    else if (argc == 1 && RB_INTEGER_TYPE_P(arg)) {
6daba0
-        dsa = dsa_generate(NUM2INT(arg));
6daba0
-    }
6daba0
     else {
6daba0
 	pass = ossl_pem_passwd_value(pass);
6daba0
 	arg = ossl_to_der_if_possible(arg);
6daba0
@@ -553,7 +464,6 @@ Init_ossl_dsa(void)
6daba0
      */
6daba0
     cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
6daba0
 
6daba0
-    rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1);
6daba0
     rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
6daba0
     rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
6daba0
 
6daba0
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
6daba0
index 4bf8a7b374..85bb6ec0ae 100644
6daba0
--- a/test/openssl/test_pkey_dsa.rb
6daba0
+++ b/test/openssl/test_pkey_dsa.rb
6daba0
@@ -5,31 +5,26 @@
6daba0
 
6daba0
 class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
6daba0
   def test_private
6daba0
-    key = OpenSSL::PKey::DSA.new(256)
6daba0
-    assert(key.private?)
6daba0
+    key = Fixtures.pkey("dsa1024")
6daba0
+    assert_equal true, key.private?
6daba0
     key2 = OpenSSL::PKey::DSA.new(key.to_der)
6daba0
-    assert(key2.private?)
6daba0
+    assert_equal true, key2.private?
6daba0
     key3 = key.public_key
6daba0
-    assert(!key3.private?)
6daba0
+    assert_equal false, key3.private?
6daba0
     key4 = OpenSSL::PKey::DSA.new(key3.to_der)
6daba0
-    assert(!key4.private?)
6daba0
+    assert_equal false, key4.private?
6daba0
   end
6daba0
 
6daba0
   def test_new
6daba0
-    key = OpenSSL::PKey::DSA.new 256
6daba0
+    key = OpenSSL::PKey::DSA.new(2048)
6daba0
     pem  = key.public_key.to_pem
6daba0
     OpenSSL::PKey::DSA.new pem
6daba0
-    if $0 == __FILE__
6daba0
-      assert_nothing_raised {
6daba0
-        key = OpenSSL::PKey::DSA.new 2048
6daba0
-      }
6daba0
-    end
6daba0
   end
6daba0
 
6daba0
   def test_new_break
6daba0
-    assert_nil(OpenSSL::PKey::DSA.new(512) { break })
6daba0
+    assert_nil(OpenSSL::PKey::DSA.new(2048) { break })
6daba0
     assert_raise(RuntimeError) do
6daba0
-      OpenSSL::PKey::DSA.new(512) { raise }
6daba0
+      OpenSSL::PKey::DSA.new(2048) { raise }
6daba0
     end
6daba0
   end
6daba0
 
6daba0
@@ -184,7 +179,7 @@ def test_read_DSAPublicKey_pem
6daba0
   end
6daba0
 
6daba0
   def test_dup
6daba0
-    key = OpenSSL::PKey::DSA.new(256)
6daba0
+    key = Fixtures.pkey("dsa1024")
6daba0
     key2 = key.dup
6daba0
     assert_equal key.params, key2.params
6daba0
     key2.set_pqg(key2.p + 1, key2.q, key2.g)
6daba0
-- 
6daba0
2.32.0
6daba0
6daba0
6daba0
From ba5a3a5c3eabf969f5cd2232b022e440af803b5b Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Mon, 5 Apr 2021 00:39:04 +0900
6daba0
Subject: [PATCH 5/5] pkey: remove unused ossl_generate_cb_2() helper function
6daba0
6daba0
The previous series of commits re-implemented key generation with the
6daba0
low level API with the EVP API. The BN_GENCB-based callback function is
6daba0
no longer used.
6daba0
---
6daba0
 ext/openssl/extconf.rb        |  3 --
6daba0
 ext/openssl/openssl_missing.h | 12 ------
6daba0
 ext/openssl/ossl_pkey.c       | 73 +++++++----------------------------
6daba0
 ext/openssl/ossl_pkey.h       |  8 ----
6daba0
 4 files changed, 15 insertions(+), 81 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
6daba0
index 693e55cd97..b3c6647faf 100644
6daba0
--- a/ext/openssl/extconf.rb
6daba0
+++ b/ext/openssl/extconf.rb
6daba0
@@ -136,9 +136,6 @@ def find_openssl_library
6daba0
   $defs.push("-DHAVE_OPAQUE_OPENSSL")
6daba0
 end
6daba0
 have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API")
6daba0
-have_func("BN_GENCB_new")
6daba0
-have_func("BN_GENCB_free")
6daba0
-have_func("BN_GENCB_get_arg")
6daba0
 have_func("EVP_MD_CTX_new")
6daba0
 have_func("EVP_MD_CTX_free")
6daba0
 have_func("EVP_MD_CTX_pkey_ctx")
6daba0
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
6daba0
index 7d218f86f5..e575415f49 100644
6daba0
--- a/ext/openssl/openssl_missing.h
6daba0
+++ b/ext/openssl/openssl_missing.h
6daba0
@@ -34,18 +34,6 @@ int ossl_EC_curve_nist2nid(const char *);
6daba0
 #endif
6daba0
 
6daba0
 /* added in 1.1.0 */
6daba0
-#if !defined(HAVE_BN_GENCB_NEW)
6daba0
-#  define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB)))
6daba0
-#endif
6daba0
-
6daba0
-#if !defined(HAVE_BN_GENCB_FREE)
6daba0
-#  define BN_GENCB_free(cb) OPENSSL_free(cb)
6daba0
-#endif
6daba0
-
6daba0
-#if !defined(HAVE_BN_GENCB_GET_ARG)
6daba0
-#  define BN_GENCB_get_arg(cb) (cb)->arg
6daba0
-#endif
6daba0
-
6daba0
 #if !defined(HAVE_EVP_MD_CTX_NEW)
6daba0
 #  define EVP_MD_CTX_new EVP_MD_CTX_create
6daba0
 #endif
6daba0
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
6daba0
index d76f0600d1..f9282b9417 100644
6daba0
--- a/ext/openssl/ossl_pkey.c
6daba0
+++ b/ext/openssl/ossl_pkey.c
6daba0
@@ -17,64 +17,6 @@ VALUE cPKey;
6daba0
 VALUE ePKeyError;
6daba0
 static ID id_private_q;
6daba0
 
6daba0
-/*
6daba0
- * callback for generating keys
6daba0
- */
6daba0
-static VALUE
6daba0
-call_check_ints0(VALUE arg)
6daba0
-{
6daba0
-    rb_thread_check_ints();
6daba0
-    return Qnil;
6daba0
-}
6daba0
-
6daba0
-static void *
6daba0
-call_check_ints(void *arg)
6daba0
-{
6daba0
-    int state;
6daba0
-    rb_protect(call_check_ints0, Qnil, &state);
6daba0
-    return (void *)(VALUE)state;
6daba0
-}
6daba0
-
6daba0
-int
6daba0
-ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
6daba0
-{
6daba0
-    VALUE ary;
6daba0
-    struct ossl_generate_cb_arg *arg;
6daba0
-    int state;
6daba0
-
6daba0
-    arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb);
6daba0
-    if (arg->yield) {
6daba0
-	ary = rb_ary_new2(2);
6daba0
-	rb_ary_store(ary, 0, INT2NUM(p));
6daba0
-	rb_ary_store(ary, 1, INT2NUM(n));
6daba0
-
6daba0
-	/*
6daba0
-	* can be break by raising exception or 'break'
6daba0
-	*/
6daba0
-	rb_protect(rb_yield, ary, &state);
6daba0
-	if (state) {
6daba0
-	    arg->state = state;
6daba0
-	    return 0;
6daba0
-	}
6daba0
-    }
6daba0
-    if (arg->interrupted) {
6daba0
-	arg->interrupted = 0;
6daba0
-	state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
6daba0
-	if (state) {
6daba0
-	    arg->state = state;
6daba0
-	    return 0;
6daba0
-	}
6daba0
-    }
6daba0
-    return 1;
6daba0
-}
6daba0
-
6daba0
-void
6daba0
-ossl_generate_cb_stop(void *ptr)
6daba0
-{
6daba0
-    struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
6daba0
-    arg->interrupted = 1;
6daba0
-}
6daba0
-
6daba0
 static void
6daba0
 ossl_evp_pkey_free(void *ptr)
6daba0
 {
6daba0
@@ -257,6 +199,21 @@ pkey_gen_cb_yield(VALUE ctx_v)
6daba0
     return rb_yield_values2(info_num, argv);
6daba0
 }
6daba0
 
6daba0
+static VALUE
6daba0
+call_check_ints0(VALUE arg)
6daba0
+{
6daba0
+    rb_thread_check_ints();
6daba0
+    return Qnil;
6daba0
+}
6daba0
+
6daba0
+static void *
6daba0
+call_check_ints(void *arg)
6daba0
+{
6daba0
+    int state;
6daba0
+    rb_protect(call_check_ints0, Qnil, &state);
6daba0
+    return (void *)(VALUE)state;
6daba0
+}
6daba0
+
6daba0
 static int
6daba0
 pkey_gen_cb(EVP_PKEY_CTX *ctx)
6daba0
 {
6daba0
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
6daba0
index 7dbaed47bc..629c16ae1f 100644
6daba0
--- a/ext/openssl/ossl_pkey.h
6daba0
+++ b/ext/openssl/ossl_pkey.h
6daba0
@@ -35,14 +35,6 @@ extern const rb_data_type_t ossl_evp_pkey_type;
6daba0
     } \
6daba0
 } while (0)
6daba0
 
6daba0
-struct ossl_generate_cb_arg {
6daba0
-    int yield;
6daba0
-    int interrupted;
6daba0
-    int state;
6daba0
-};
6daba0
-int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);
6daba0
-void ossl_generate_cb_stop(void *ptr);
6daba0
-
6daba0
 VALUE ossl_pkey_new(EVP_PKEY *);
6daba0
 void ossl_pkey_check_public_key(const EVP_PKEY *);
6daba0
 EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE);
6daba0
-- 
6daba0
2.32.0
6daba0