diff --git a/.gitignore b/.gitignore index f554dcd..a59f941 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -SOURCES/ruby-3.1.2.tar.xz -/ruby-3.1.2.tar.xz +/*/ +/ruby-*.tar.xz +/*.rpm diff --git a/.ruby.metadata b/.ruby.metadata new file mode 100644 index 0000000..d0dd1ac --- /dev/null +++ b/.ruby.metadata @@ -0,0 +1 @@ +4c47f1dfeeb23fc55d65bcae50cf70c23bc28aa3 ruby-3.1.2.tar.xz diff --git a/gating.yaml b/gating.yaml deleted file mode 100644 index c190bde..0000000 --- a/gating.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- !Policy -product_versions: - - rhel-9 -decision_context: osci_compose_gate -rules: - - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional} diff --git a/ruby-3.0.3-ext-openssl-extconf.rb-require-OpenSSL-version-1.0.1.patch b/ruby-3.0.3-ext-openssl-extconf.rb-require-OpenSSL-version-1.0.1.patch deleted file mode 100644 index 4b8e9ab..0000000 --- a/ruby-3.0.3-ext-openssl-extconf.rb-require-OpenSSL-version-1.0.1.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 202ff1372a40a8adf9aac74bfe8a39141b0c57e5 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 27 Sep 2021 00:38:38 +0900 -Subject: [PATCH] ext/openssl/extconf.rb: require OpenSSL version >= 1.0.1, < 3 - -Ruby/OpenSSL 2.1.x and 2.2.x will not support OpenSSL 3.0 API. Let's -make extconf.rb explicitly check the version number to be within the -acceptable range, since it will not compile anyway. - -Reference: https://bugs.ruby-lang.org/issues/18192 ---- - ext/openssl/extconf.rb | 43 ++++++++++++++++++++++++------------------ - 1 file changed, 25 insertions(+), 18 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 264130bb..7e817ae2 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -33,9 +33,6 @@ - have_library("ws2_32") - end - --Logging::message "=== Checking for required stuff... ===\n" --result = pkg_config("openssl") && have_header("openssl/ssl.h") -- - if $mingw - append_cflags '-D_FORTIFY_SOURCE=2' - append_ldflags '-fstack-protector' -@@ -92,19 +89,33 @@ def find_openssl_library - return false - end - --unless result -- unless find_openssl_library -- Logging::message "=== Checking for required stuff failed. ===\n" -- Logging::message "Makefile wasn't created. Fix the errors above.\n" -- raise "OpenSSL library could not be found. You might want to use " \ -- "--with-openssl-dir= option to specify the prefix where OpenSSL " \ -- "is installed." -- end -+Logging::message "=== Checking for required stuff... ===\n" -+pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h") -+ -+if !pkg_config_found && !find_openssl_library -+ Logging::message "=== Checking for required stuff failed. ===\n" -+ Logging::message "Makefile wasn't created. Fix the errors above.\n" -+ raise "OpenSSL library could not be found. You might want to use " \ -+ "--with-openssl-dir= option to specify the prefix where OpenSSL " \ -+ "is installed." - end - --unless checking_for("OpenSSL version is 1.0.1 or later") { -- try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") } -- raise "OpenSSL >= 1.0.1 or LibreSSL is required" -+version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") -+ is_libressl = true -+ checking_for("LibreSSL version >= 2.5.0") { -+ try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") } -+else -+ checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") { -+ try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") && -+ !try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") } -+end -+unless version_ok -+ raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required" -+end -+ -+# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h -+if is_libressl && ($mswin || $mingw) -+ $defs.push("-DNOCRYPT") - end - - Logging::message "=== Checking for OpenSSL features... ===\n" -@@ -116,10 +127,6 @@ def find_openssl_library - have_func("ENGINE_load_#{name}()", "openssl/engine.h") - } - --if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") -- $defs.push("-DNOCRYPT") --end -- - # added in 1.0.2 - have_func("EC_curve_nist2nid") - have_func("X509_REVOKED_dup") diff --git a/ruby-3.1.0-Add-more-support-for-generic-pkey-types.patch b/ruby-3.1.0-Add-more-support-for-generic-pkey-types.patch deleted file mode 100644 index cede1aa..0000000 --- a/ruby-3.1.0-Add-more-support-for-generic-pkey-types.patch +++ /dev/null @@ -1,1004 +0,0 @@ -From 6bbdaef1a578fdbfc6a5bf82402ba4d3fd733d4a Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 21 Mar 2017 18:23:53 +0900 -Subject: [PATCH 1/6] pkey: assume generic PKeys contain private components - -The EVP interface cannot tell whether if a pkey contains the private -components or not. Assume it does if it does not respond to #private?. -This fixes the NoMethodError on calling #sign on a generic PKey. ---- - ext/openssl/ossl_pkey.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 610a83fd2d..8d41623e80 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -252,12 +252,19 @@ GetPrivPKeyPtr(VALUE obj) - { - EVP_PKEY *pkey; - -- if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) { -- ossl_raise(rb_eArgError, "Private key is needed."); -- } - GetPKey(obj, pkey); -+ if (OSSL_PKEY_IS_PRIVATE(obj)) -+ return pkey; -+ /* -+ * The EVP API does not provide a way to check if the EVP_PKEY has private -+ * components. Assuming it does... -+ */ -+ if (!rb_respond_to(obj, id_private_q)) -+ return pkey; -+ if (RTEST(rb_funcallv(obj, id_private_q, 0, NULL))) -+ return pkey; - -- return pkey; -+ rb_raise(rb_eArgError, "private key is needed"); - } - - EVP_PKEY * --- -2.32.0 - - -From 86508f74b3d41166ed6091b7b31f18a26478c347 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 20 Mar 2017 23:18:26 +0900 -Subject: [PATCH 2/6] pkey: add PKey.generate_parameters and .generate_key - -Add two methods to create a PKey using the generic EVP interface. This -is useful for the PKey types we don't have a dedicated class. ---- - ext/openssl/ossl_pkey.c | 222 ++++++++++++++++++++++++++++++++++++++ - test/openssl/test_pkey.rb | 43 ++++++++ - 2 files changed, 265 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 8d41623e80..1f3dd39b9b 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -197,6 +197,226 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) - return ossl_pkey_new(pkey); - } - -+static VALUE -+pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) -+{ -+ VALUE key = rb_ary_entry(i, 0), value = rb_ary_entry(i, 1); -+ EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)ctx_v; -+ -+ if (SYMBOL_P(key)) -+ key = rb_sym2str(key); -+ value = rb_String(value); -+ -+ if (EVP_PKEY_CTX_ctrl_str(ctx, StringValueCStr(key), StringValueCStr(value)) <= 0) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_ctrl_str(ctx, %+"PRIsVALUE", %+"PRIsVALUE")", -+ key, value); -+ return Qnil; -+} -+ -+static VALUE -+pkey_gen_apply_options0(VALUE args_v) -+{ -+ VALUE *args = (VALUE *)args_v; -+ -+ rb_block_call(args[1], rb_intern("each"), 0, NULL, -+ pkey_gen_apply_options_i, args[0]); -+ return Qnil; -+} -+ -+struct pkey_blocking_generate_arg { -+ EVP_PKEY_CTX *ctx; -+ EVP_PKEY *pkey; -+ int state; -+ int yield: 1; -+ int genparam: 1; -+ int stop: 1; -+}; -+ -+static VALUE -+pkey_gen_cb_yield(VALUE ctx_v) -+{ -+ EVP_PKEY_CTX *ctx = (void *)ctx_v; -+ int i, info_num; -+ VALUE *argv; -+ -+ info_num = EVP_PKEY_CTX_get_keygen_info(ctx, -1); -+ argv = ALLOCA_N(VALUE, info_num); -+ for (i = 0; i < info_num; i++) -+ argv[i] = INT2NUM(EVP_PKEY_CTX_get_keygen_info(ctx, i)); -+ -+ return rb_yield_values2(info_num, argv); -+} -+ -+static int -+pkey_gen_cb(EVP_PKEY_CTX *ctx) -+{ -+ struct pkey_blocking_generate_arg *arg = EVP_PKEY_CTX_get_app_data(ctx); -+ -+ if (arg->yield) { -+ int state; -+ rb_protect(pkey_gen_cb_yield, (VALUE)ctx, &state); -+ if (state) { -+ arg->stop = 1; -+ arg->state = state; -+ } -+ } -+ return !arg->stop; -+} -+ -+static void -+pkey_blocking_gen_stop(void *ptr) -+{ -+ struct pkey_blocking_generate_arg *arg = ptr; -+ arg->stop = 1; -+} -+ -+static void * -+pkey_blocking_gen(void *ptr) -+{ -+ struct pkey_blocking_generate_arg *arg = ptr; -+ -+ if (arg->genparam && EVP_PKEY_paramgen(arg->ctx, &arg->pkey) <= 0) -+ return NULL; -+ if (!arg->genparam && EVP_PKEY_keygen(arg->ctx, &arg->pkey) <= 0) -+ return NULL; -+ return arg->pkey; -+} -+ -+static VALUE -+pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) -+{ -+ EVP_PKEY_CTX *ctx; -+ VALUE alg, options; -+ struct pkey_blocking_generate_arg gen_arg = { 0 }; -+ int state; -+ -+ rb_scan_args(argc, argv, "11", &alg, &options); -+ if (rb_obj_is_kind_of(alg, cPKey)) { -+ EVP_PKEY *base_pkey; -+ -+ GetPKey(alg, base_pkey); -+ ctx = EVP_PKEY_CTX_new(base_pkey, NULL/* engine */); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ } -+ else { -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ ENGINE *tmpeng; -+ int pkey_id; -+ -+ StringValue(alg); -+ ameth = EVP_PKEY_asn1_find_str(&tmpeng, RSTRING_PTR(alg), -+ RSTRING_LENINT(alg)); -+ if (!ameth) -+ ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", alg); -+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); -+#if !defined(OPENSSL_NO_ENGINE) -+ if (tmpeng) -+ ENGINE_finish(tmpeng); -+#endif -+ -+ ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id"); -+ } -+ -+ if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_paramgen_init"); -+ } -+ if (!genparam && EVP_PKEY_keygen_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_keygen_init"); -+ } -+ -+ if (!NIL_P(options)) { -+ VALUE args[2]; -+ -+ args[0] = (VALUE)ctx; -+ args[1] = options; -+ rb_protect(pkey_gen_apply_options0, (VALUE)args, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ -+ gen_arg.genparam = genparam; -+ gen_arg.ctx = ctx; -+ gen_arg.yield = rb_block_given_p(); -+ EVP_PKEY_CTX_set_app_data(ctx, &gen_arg); -+ EVP_PKEY_CTX_set_cb(ctx, pkey_gen_cb); -+ if (gen_arg.yield) -+ pkey_blocking_gen(&gen_arg); -+ else -+ rb_thread_call_without_gvl(pkey_blocking_gen, &gen_arg, -+ pkey_blocking_gen_stop, &gen_arg); -+ EVP_PKEY_CTX_free(ctx); -+ if (!gen_arg.pkey) { -+ if (gen_arg.state) { -+ ossl_clear_error(); -+ rb_jump_tag(gen_arg.state); -+ } -+ else { -+ ossl_raise(ePKeyError, genparam ? "EVP_PKEY_paramgen" : "EVP_PKEY_keygen"); -+ } -+ } -+ -+ return ossl_pkey_new(gen_arg.pkey); -+} -+ -+/* -+ * call-seq: -+ * OpenSSL::PKey.generate_parameters(algo_name [, options]) -> pkey -+ * -+ * Generates new parameters for the algorithm. _algo_name_ is a String that -+ * represents the algorithm. The optional argument _options_ is a Hash that -+ * specifies the options specific to the algorithm. The order of the options -+ * can be important. -+ * -+ * A block can be passed optionally. The meaning of the arguments passed to -+ * the block varies depending on the implementation of the algorithm. The block -+ * may be called once or multiple times, or may not even be called. -+ * -+ * For the supported options, see the documentation for the 'openssl genpkey' -+ * utility command. -+ * -+ * == Example -+ * pkey = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048) -+ * p pkey.p.num_bits #=> 2048 -+ */ -+static VALUE -+ossl_pkey_s_generate_parameters(int argc, VALUE *argv, VALUE self) -+{ -+ return pkey_generate(argc, argv, self, 1); -+} -+ -+/* -+ * call-seq: -+ * OpenSSL::PKey.generate_key(algo_name [, options]) -> pkey -+ * OpenSSL::PKey.generate_key(pkey [, options]) -> pkey -+ * -+ * Generates a new key (pair). -+ * -+ * If a String is given as the first argument, it generates a new random key -+ * for the algorithm specified by the name just as ::generate_parameters does. -+ * If an OpenSSL::PKey::PKey is given instead, it generates a new random key -+ * for the same algorithm as the key, using the parameters the key contains. -+ * -+ * See ::generate_parameters for the details of _options_ and the given block. -+ * -+ * == Example -+ * pkey_params = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048) -+ * pkey_params.priv_key #=> nil -+ * pkey = OpenSSL::PKey.generate_key(pkey_params) -+ * pkey.priv_key #=> # 512, -+ "dsa_paramgen_q_bits" => 256, -+ }) -+ assert_instance_of OpenSSL::PKey::DSA, pkey -+ assert_equal 512, pkey.p.num_bits -+ assert_equal 256, pkey.q.num_bits -+ assert_equal nil, pkey.priv_key -+ -+ # Invalid options are checked -+ assert_raise(OpenSSL::PKey::PKeyError) { -+ OpenSSL::PKey.generate_parameters("DSA", "invalid" => "option") -+ } -+ -+ # Parameter generation callback is called -+ cb_called = [] -+ assert_raise(RuntimeError) { -+ OpenSSL::PKey.generate_parameters("DSA") { |*args| -+ cb_called << args -+ raise "exit!" if cb_called.size == 3 -+ } -+ } -+ assert_not_empty cb_called -+ end -+ -+ def test_s_generate_key -+ assert_raise(OpenSSL::PKey::PKeyError) { -+ # DSA key pair cannot be generated without parameters -+ OpenSSL::PKey.generate_key("DSA") -+ } -+ pkey_params = OpenSSL::PKey.generate_parameters("DSA", { -+ "dsa_paramgen_bits" => 512, -+ "dsa_paramgen_q_bits" => 256, -+ }) -+ pkey = OpenSSL::PKey.generate_key(pkey_params) -+ assert_instance_of OpenSSL::PKey::DSA, pkey -+ assert_equal 512, pkey.p.num_bits -+ assert_not_equal nil, pkey.priv_key -+ end - end --- -2.32.0 - - -From 5713605e70c96e3215aab0e0341548af29b5088e Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 15 May 2017 23:47:47 +0900 -Subject: [PATCH 3/6] pkey: port PKey::PKey#sign and #verify to the EVP_Digest* - interface - -Use EVP_DigestSign*() and EVP_DigestVerify*() interface instead of the -old EVP_Sign*() and EVP_Verify*() functions. They were added in OpenSSL -1.0.0. - -Also, allow the digest to be specified as nil, as certain EVP_PKEY types -don't expect a digest algorithm. ---- - ext/openssl/ossl_pkey.c | 90 ++++++++++++++++++++++----------------- - test/openssl/test_pkey.rb | 12 ++++++ - 2 files changed, 63 insertions(+), 39 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 1f3dd39b9b..a0d73f5821 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -753,35 +753,47 @@ static VALUE - ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - { - EVP_PKEY *pkey; -- const EVP_MD *md; -+ const EVP_MD *md = NULL; - EVP_MD_CTX *ctx; -- unsigned int buf_len; -- VALUE str; -- int result; -+ size_t siglen; -+ int state; -+ VALUE sig; - - pkey = GetPrivPKeyPtr(self); -- md = ossl_evp_get_digestbyname(digest); -+ if (!NIL_P(digest)) -+ md = ossl_evp_get_digestbyname(digest); - StringValue(data); -- str = rb_str_new(0, EVP_PKEY_size(pkey)); - - ctx = EVP_MD_CTX_new(); - if (!ctx) -- ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -- if (!EVP_SignInit_ex(ctx, md, NULL)) { -- EVP_MD_CTX_free(ctx); -- ossl_raise(ePKeyError, "EVP_SignInit_ex"); -+ ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -+ if (EVP_DigestSignInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSignInit"); -+ } -+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSignUpdate"); -+ } -+ if (EVP_DigestSignFinal(ctx, NULL, &siglen) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } -- if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) { -- EVP_MD_CTX_free(ctx); -- ossl_raise(ePKeyError, "EVP_SignUpdate"); -+ if (siglen > LONG_MAX) -+ rb_raise(ePKeyError, "signature would be too large"); -+ sig = ossl_str_new(NULL, (long)siglen, &state); -+ if (state) { -+ EVP_MD_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig), -+ &siglen) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } -- result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey); - EVP_MD_CTX_free(ctx); -- if (!result) -- ossl_raise(ePKeyError, "EVP_SignFinal"); -- rb_str_set_len(str, buf_len); -- -- return str; -+ rb_str_set_len(sig, siglen); -+ return sig; - } - - /* -@@ -809,38 +821,38 @@ static VALUE - ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) - { - EVP_PKEY *pkey; -- const EVP_MD *md; -+ const EVP_MD *md = NULL; - EVP_MD_CTX *ctx; -- int siglen, result; -+ int ret; - - GetPKey(self, pkey); - ossl_pkey_check_public_key(pkey); -- md = ossl_evp_get_digestbyname(digest); -+ if (!NIL_P(digest)) -+ md = ossl_evp_get_digestbyname(digest); - StringValue(sig); -- siglen = RSTRING_LENINT(sig); - StringValue(data); - - ctx = EVP_MD_CTX_new(); - if (!ctx) -- ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -- if (!EVP_VerifyInit_ex(ctx, md, NULL)) { -- EVP_MD_CTX_free(ctx); -- ossl_raise(ePKeyError, "EVP_VerifyInit_ex"); -+ ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -+ if (EVP_DigestVerifyInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); - } -- if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) { -- EVP_MD_CTX_free(ctx); -- ossl_raise(ePKeyError, "EVP_VerifyUpdate"); -+ if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate"); - } -- result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey); -+ ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), -+ RSTRING_LEN(sig)); - EVP_MD_CTX_free(ctx); -- switch (result) { -- case 0: -- ossl_clear_error(); -- return Qfalse; -- case 1: -- return Qtrue; -- default: -- ossl_raise(ePKeyError, "EVP_VerifyFinal"); -+ if (ret < 0) -+ ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); -+ if (ret) -+ return Qtrue; -+ else { -+ ossl_clear_error(); -+ return Qfalse; - } - } - -diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb -index a325a1ea2b..247ba84f83 100644 ---- a/test/openssl/test_pkey.rb -+++ b/test/openssl/test_pkey.rb -@@ -68,4 +68,16 @@ def test_s_generate_key - assert_equal 512, pkey.p.num_bits - assert_not_equal nil, pkey.priv_key - end -+ -+ def test_hmac_sign_verify -+ pkey = OpenSSL::PKey.generate_key("HMAC", { "key" => "abcd" }) -+ -+ hmac = OpenSSL::HMAC.new("abcd", "SHA256").update("data").digest -+ assert_equal hmac, pkey.sign("SHA256", "data") -+ -+ # EVP_PKEY_HMAC does not support verify -+ assert_raise(OpenSSL::PKey::PKeyError) { -+ pkey.verify("SHA256", "data", hmac) -+ } -+ end - end --- -2.32.0 - - -From 76566a2e1bab42a2e1587ecbec23779ee00020fc Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 15 May 2017 23:47:47 +0900 -Subject: [PATCH 4/6] pkey: support 'one-shot' signing and verification - -OpenSSL 1.1.1 added EVP_DigestSign() and EVP_DigestVerify() functions -to the interface. Some EVP_PKEY methods such as PureEdDSA algorithms -do not support the streaming mechanism and require us to use them. ---- - ext/openssl/ossl_pkey.c | 30 ++++++++++++++++++++++++++ - test/openssl/test_pkey.rb | 45 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 75 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index a0d73f5821..19544ec7f0 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -771,6 +771,26 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignInit"); - } -+#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) -+ if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSign"); -+ } -+ if (siglen > LONG_MAX) -+ rb_raise(ePKeyError, "signature would be too large"); -+ sig = ossl_str_new(NULL, (long)siglen, &state); -+ if (state) { -+ EVP_MD_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_DigestSign(ctx, (unsigned char *)RSTRING_PTR(sig), &siglen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) < 1) { -+ EVP_MD_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_DigestSign"); -+ } -+#else - if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignUpdate"); -@@ -791,6 +811,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } -+#endif - EVP_MD_CTX_free(ctx); - rb_str_set_len(sig, siglen); - return sig; -@@ -839,6 +860,14 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); - } -+#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) -+ ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), -+ RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)); -+ EVP_MD_CTX_free(ctx); -+ if (ret < 0) -+ ossl_raise(ePKeyError, "EVP_DigestVerify"); -+#else - if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate"); -@@ -848,6 +877,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) - EVP_MD_CTX_free(ctx); - if (ret < 0) - ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); -+#endif - if (ret) - return Qtrue; - else { -diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb -index 247ba84f83..d811b9c75f 100644 ---- a/test/openssl/test_pkey.rb -+++ b/test/openssl/test_pkey.rb -@@ -80,4 +80,49 @@ def test_hmac_sign_verify - pkey.verify("SHA256", "data", hmac) - } - end -+ -+ def test_ed25519 -+ # Test vector from RFC 8032 Section 7.1 TEST 2 -+ priv_pem = <<~EOF -+ -----BEGIN PRIVATE KEY----- -+ MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7 -+ -----END PRIVATE KEY----- -+ EOF -+ pub_pem = <<~EOF -+ -----BEGIN PUBLIC KEY----- -+ MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw= -+ -----END PUBLIC KEY----- -+ EOF -+ begin -+ priv = OpenSSL::PKey.read(priv_pem) -+ pub = OpenSSL::PKey.read(pub_pem) -+ rescue OpenSSL::PKey::PKeyError -+ # OpenSSL < 1.1.1 -+ pend "Ed25519 is not implemented" -+ end -+ assert_instance_of OpenSSL::PKey::PKey, priv -+ assert_instance_of OpenSSL::PKey::PKey, pub -+ assert_equal priv_pem, priv.private_to_pem -+ assert_equal pub_pem, priv.public_to_pem -+ assert_equal pub_pem, pub.public_to_pem -+ -+ sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*") -+ 92a009a9f0d4cab8720e820b5f642540 -+ a2b27b5416503f8fb3762223ebdb69da -+ 085ac1e43e15996e458f3613d0f11d8c -+ 387b2eaeb4302aeeb00d291612bb0c00 -+ EOF -+ data = ["72"].pack("H*") -+ assert_equal sig, priv.sign(nil, data) -+ assert_equal true, priv.verify(nil, sig, data) -+ assert_equal true, pub.verify(nil, sig, data) -+ assert_equal false, pub.verify(nil, sig, data.succ) -+ -+ # PureEdDSA wants nil as the message digest -+ assert_raise(OpenSSL::PKey::PKeyError) { priv.sign("SHA512", data) } -+ assert_raise(OpenSSL::PKey::PKeyError) { pub.verify("SHA512", sig, data) } -+ -+ # Ed25519 pkey type does not support key derivation -+ assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) } -+ end - end --- -2.32.0 - - -From fabdd22bddc572ba3342ec0b09e3fef8ed6245b8 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 18 Mar 2017 21:58:46 +0900 -Subject: [PATCH 5/6] pkey: add PKey::PKey#derive - -Add OpenSSL::PKey::PKey#derive as the wrapper for EVP_PKEY_CTX_derive(). -This is useful for pkey types that we don't have dedicated classes, such -as X25519. ---- - ext/openssl/ossl_pkey.c | 52 ++++++++++++++++++++++++++++++++++++ - test/openssl/test_pkey.rb | 26 ++++++++++++++++++ - test/openssl/test_pkey_dh.rb | 13 +++++++++ - test/openssl/test_pkey_ec.rb | 16 +++++++++++ - 4 files changed, 107 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 19544ec7f0..df8b425a0f 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -886,6 +886,57 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) - } - } - -+/* -+ * call-seq: -+ * pkey.derive(peer_pkey) -> string -+ * -+ * Derives a shared secret from _pkey_ and _peer_pkey_. _pkey_ must contain -+ * the private components, _peer_pkey_ must contain the public components. -+ */ -+static VALUE -+ossl_pkey_derive(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey, *peer_pkey; -+ EVP_PKEY_CTX *ctx; -+ VALUE peer_pkey_obj, str; -+ size_t keylen; -+ int state; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "1", &peer_pkey_obj); -+ GetPKey(peer_pkey_obj, peer_pkey); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_derive_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_derive_init"); -+ } -+ if (EVP_PKEY_derive_set_peer(ctx, peer_pkey) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_derive_set_peer"); -+ } -+ if (EVP_PKEY_derive(ctx, NULL, &keylen) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_derive"); -+ } -+ if (keylen > LONG_MAX) -+ rb_raise(ePKeyError, "derived key would be too large"); -+ str = ossl_str_new(NULL, (long)keylen, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_PKEY_derive(ctx, (unsigned char *)RSTRING_PTR(str), &keylen) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_derive"); -+ } -+ EVP_PKEY_CTX_free(ctx); -+ rb_str_set_len(str, keylen); -+ return str; -+} -+ - /* - * INIT - */ -@@ -983,6 +1034,7 @@ Init_ossl_pkey(void) - - rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); - rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); -+ rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); - - id_private_q = rb_intern("private?"); - -diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb -index d811b9c75f..5307fe5b08 100644 ---- a/test/openssl/test_pkey.rb -+++ b/test/openssl/test_pkey.rb -@@ -125,4 +125,30 @@ def test_ed25519 - # Ed25519 pkey type does not support key derivation - assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) } - end -+ -+ def test_x25519 -+ # Test vector from RFC 7748 Section 6.1 -+ alice_pem = <<~EOF -+ -----BEGIN PRIVATE KEY----- -+ MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq -+ -----END PRIVATE KEY----- -+ EOF -+ bob_pem = <<~EOF -+ -----BEGIN PUBLIC KEY----- -+ MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08= -+ -----END PUBLIC KEY----- -+ EOF -+ shared_secret = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" -+ begin -+ alice = OpenSSL::PKey.read(alice_pem) -+ bob = OpenSSL::PKey.read(bob_pem) -+ rescue OpenSSL::PKey::PKeyError -+ # OpenSSL < 1.1.0 -+ pend "X25519 is not implemented" -+ end -+ assert_instance_of OpenSSL::PKey::PKey, alice -+ assert_equal alice_pem, alice.private_to_pem -+ assert_equal bob_pem, bob.public_to_pem -+ assert_equal [shared_secret].pack("H*"), alice.derive(bob) -+ end - end -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index 4a05626a12..9efc3ba68d 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -18,6 +18,19 @@ def test_new_break - end - end - -+ def test_derive_key -+ dh1 = Fixtures.pkey("dh1024").generate_key! -+ dh2 = Fixtures.pkey("dh1024").generate_key! -+ 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_equal z, dh1.compute_key(dh2.pub_key) -+ assert_equal z, dh2.compute_key(dh1.pub_key) -+ end -+ - def test_DHparams - dh1024 = Fixtures.pkey("dh1024") - asn1 = OpenSSL::ASN1::Sequence([ -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index a0e6a23ff8..95d4338a51 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -93,6 +93,22 @@ def test_sign_verify - assert_equal false, p256.verify("SHA256", signature1, data) - end - -+ def test_derive_key -+ # NIST CAVP, KAS_ECC_CDH_PrimitiveTest.txt, P-256 COUNT = 0 -+ qCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" -+ qCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac" -+ dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534" -+ zIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" -+ a = OpenSSL::PKey::EC.new("prime256v1") -+ a.private_key = OpenSSL::BN.new(dIUT, 16) -+ b = OpenSSL::PKey::EC.new("prime256v1") -+ uncompressed = OpenSSL::BN.new("04" + qCAVSx + qCAVSy, 16) -+ b.public_key = OpenSSL::PKey::EC::Point.new(b.group, uncompressed) -+ assert_equal [zIUT].pack("H*"), a.derive(b) -+ -+ assert_equal a.derive(b), a.dh_compute_key(b.public_key) -+ end -+ - def test_dsa_sign_verify - data1 = "foo" - data2 = "bar" --- -2.32.0 - - -From 97078c7fa8a724c7c71f9850d31fc401239da228 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 18 Mar 2017 22:34:19 +0900 -Subject: [PATCH 6/6] pkey: reimplement PKey::DH#compute_key and - PKey::EC#dh_compute_key - -Use the new OpenSSL::PKey::PKey#derive instead of the raw -{EC,}DH_compute_key(), mainly to reduce amount of the C code. ---- - ext/openssl/lib/openssl/pkey.rb | 33 +++++++++++++++++++++++++++++++ - ext/openssl/ossl_pkey_dh.c | 35 --------------------------------- - ext/openssl/ossl_pkey_ec.c | 32 ------------------------------ - 3 files changed, 33 insertions(+), 67 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 9cc3276356..be60ac2beb 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -9,6 +9,24 @@ - module OpenSSL::PKey - class DH - include OpenSSL::Marshal -+ -+ # :call-seq: -+ # dh.compute_key(pub_bn) -> string -+ # -+ # Returns a String containing a shared secret computed from the other -+ # party's public value. -+ # -+ # This method is provided for backwards compatibility, and calls #derive -+ # internally. -+ # -+ # === Parameters -+ # * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by -+ # DH#public_key as that contains the DH parameters only. -+ def compute_key(pub_bn) -+ peer = dup -+ peer.set_key(pub_bn, nil) -+ derive(peer) -+ end - end - - class DSA -@@ -18,7 +36,22 @@ class DSA - if defined?(EC) - class EC - include OpenSSL::Marshal -+ -+ # :call-seq: -+ # ec.dh_compute_key(pubkey) -> string -+ # -+ # Derives a shared secret by ECDH. _pubkey_ must be an instance of -+ # OpenSSL::PKey::EC::Point and must belong to the same group. -+ # -+ # This method is provided for backwards compatibility, and calls #derive -+ # internally. -+ def dh_compute_key(pubkey) -+ peer = OpenSSL::PKey::EC.new(group) -+ peer.public_key = pubkey -+ derive(peer) -+ end - end -+ - class EC::Point - # :call-seq: - # point.to_bn([conversion_form]) -> OpenSSL::BN -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index bc50e5566b..5bc1c49ca1 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -476,40 +476,6 @@ ossl_dh_generate_key(VALUE self) - return self; - } - --/* -- * call-seq: -- * dh.compute_key(pub_bn) -> aString -- * -- * Returns a String containing a shared secret computed from the other party's public value. -- * See DH_compute_key() for further information. -- * -- * === Parameters -- * * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by -- * DH#public_key as that contains the DH parameters only. -- */ --static VALUE --ossl_dh_compute_key(VALUE self, VALUE pub) --{ -- DH *dh; -- const BIGNUM *pub_key, *dh_p; -- VALUE str; -- int len; -- -- GetDH(self, dh); -- DH_get0_pqg(dh, &dh_p, NULL, NULL); -- if (!dh_p) -- ossl_raise(eDHError, "incomplete DH"); -- pub_key = GetBNPtr(pub); -- len = DH_size(dh); -- str = rb_str_new(0, len); -- if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) { -- ossl_raise(eDHError, NULL); -- } -- rb_str_set_len(str, len); -- -- return str; --} -- - /* - * Document-method: OpenSSL::PKey::DH#set_pqg - * call-seq: -@@ -587,7 +553,6 @@ Init_ossl_dh(void) - 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, "compute_key", ossl_dh_compute_key, 1); - - DEF_OSSL_PKEY_BN(cDH, dh, p); - DEF_OSSL_PKEY_BN(cDH, dh, q); -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index 6fe2533e2a..c2534251c3 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -487,37 +487,6 @@ static VALUE ossl_ec_key_check_key(VALUE self) - return Qtrue; - } - --/* -- * call-seq: -- * key.dh_compute_key(pubkey) => String -- * -- * See the OpenSSL documentation for ECDH_compute_key() -- */ --static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey) --{ -- EC_KEY *ec; -- EC_POINT *point; -- int buf_len; -- VALUE str; -- -- GetEC(self, ec); -- GetECPoint(pubkey, point); -- --/* BUG: need a way to figure out the maximum string size */ -- buf_len = 1024; -- str = rb_str_new(0, buf_len); --/* BUG: take KDF as a block */ -- buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL); -- if (buf_len < 0) -- ossl_raise(eECError, "ECDH_compute_key"); -- -- rb_str_resize(str, buf_len); -- -- return str; --} -- --/* sign_setup */ -- - /* - * call-seq: - * key.dsa_sign_asn1(data) => String -@@ -1657,7 +1626,6 @@ void Init_ossl_ec(void) - rb_define_alias(cEC, "generate_key", "generate_key!"); - rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0); - -- rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1); - rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1); - rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2); - /* do_sign/do_verify */ --- -2.32.0 - diff --git a/ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch b/ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch deleted file mode 100644 index 33789b4..0000000 --- a/ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch +++ /dev/null @@ -1,630 +0,0 @@ -From 316cb2a41f154e4663d7e7fead60cfc0bfa86af9 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 12 Apr 2021 13:55:10 +0900 -Subject: [PATCH 1/2] pkey: do not check NULL argument in ossl_pkey_new() - -Passing NULL to ossl_pkey_new() makes no sense in the first place, and -in fact it is ensured not to be NULL in all cases. ---- - ext/openssl/ossl_pkey.c | 6 +----- - ext/openssl/ossl_pkey.h | 1 + - 2 files changed, 2 insertions(+), 5 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index f9f5162e..820e4a2c 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -38,12 +38,8 @@ static VALUE - pkey_new0(EVP_PKEY *pkey) - { - VALUE klass, obj; -- int type; - -- if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE) -- ossl_raise(rb_eRuntimeError, "pkey is empty"); -- -- switch (type) { -+ switch (EVP_PKEY_base_id(pkey)) { - #if !defined(OPENSSL_NO_RSA) - case EVP_PKEY_RSA: klass = cRSA; break; - #endif -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index 4beede22..f0476780 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -35,6 +35,7 @@ extern const rb_data_type_t ossl_evp_pkey_type; - } \ - } while (0) - -+/* Takes ownership of the EVP_PKEY */ - VALUE ossl_pkey_new(EVP_PKEY *); - void ossl_pkey_check_public_key(const EVP_PKEY *); - EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); - -From 74f6c6175688502a5bf27ae35367616858630c0f Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 12 Apr 2021 18:32:40 +0900 -Subject: [PATCH 2/2] pkey: allocate EVP_PKEY on #initialize - -Allocate an EVP_PKEY when the content is ready: when #initialize -or #initialize_copy is called, rather than when a T_DATA is allocated. -This is more natural because the lower level API has been deprecated -and an EVP_PKEY is becoming the minimum unit of handling keys. ---- - ext/openssl/ossl_pkey.c | 15 ++---- - ext/openssl/ossl_pkey.h | 15 ++---- - ext/openssl/ossl_pkey_dh.c | 71 +++++++++++++++++++-------- - ext/openssl/ossl_pkey_dsa.c | 93 ++++++++++++++++++++--------------- - ext/openssl/ossl_pkey_ec.c | 91 +++++++++++++++++++---------------- - ext/openssl/ossl_pkey_rsa.c | 96 ++++++++++++++++++++++--------------- - 6 files changed, 218 insertions(+), 163 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 820e4a2c..ea75d63f 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -54,8 +54,8 @@ pkey_new0(EVP_PKEY *pkey) - #endif - default: klass = cPKey; break; - } -- obj = NewPKey(klass); -- SetPKey(obj, pkey); -+ obj = rb_obj_alloc(klass); -+ RTYPEDDATA_DATA(obj) = pkey; - return obj; - } - -@@ -511,16 +511,7 @@ DupPKeyPtr(VALUE obj) - static VALUE - ossl_pkey_alloc(VALUE klass) - { -- EVP_PKEY *pkey; -- VALUE obj; -- -- obj = NewPKey(klass); -- if (!(pkey = EVP_PKEY_new())) { -- ossl_raise(ePKeyError, NULL); -- } -- SetPKey(obj, pkey); -- -- return obj; -+ return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL); - } - - /* -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index f0476780..ed18bc69 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -15,19 +15,10 @@ extern VALUE cPKey; - extern VALUE ePKeyError; - extern const rb_data_type_t ossl_evp_pkey_type; - --#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) --#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) --#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue) -+/* For ENGINE */ -+#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue) -+#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue) - --#define NewPKey(klass) \ -- TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0) --#define SetPKey(obj, pkey) do { \ -- if (!(pkey)) { \ -- rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ -- } \ -- RTYPEDDATA_DATA(obj) = (pkey); \ -- OSSL_PKEY_SET_PUBLIC(obj); \ --} while (0) - #define GetPKey(obj, pkey) do {\ - TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \ - if (!(pkey)) { \ -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index ca782bbe..04c11b21 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -72,34 +72,57 @@ static VALUE - ossl_dh_initialize(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; -+ int type; - DH *dh; -- BIO *in; -+ BIO *in = NULL; - VALUE arg; - -- GetPKey(self, pkey); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); -+ - /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - dh = DH_new(); - if (!dh) - ossl_raise(eDHError, "DH_new"); -+ goto legacy; - } -- else { -- arg = ossl_to_der_if_possible(arg); -- in = ossl_obj2bio(&arg); -- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); -- if (!dh){ -- OSSL_BIO_reset(in); -- dh = d2i_DHparams_bio(in, NULL); -- } -- BIO_free(in); -- if (!dh) { -- ossl_raise(eDHError, NULL); -- } -+ -+ arg = ossl_to_der_if_possible(arg); -+ in = ossl_obj2bio(&arg); -+ -+ /* -+ * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic -+ * routine does not support DER-encoded parameters -+ */ -+ dh = d2i_DHparams_bio(in, NULL); -+ if (dh) -+ goto legacy; -+ OSSL_BIO_reset(in); -+ -+ pkey = ossl_pkey_read_generic(in, Qnil); -+ BIO_free(in); -+ if (!pkey) -+ ossl_raise(eDHError, "could not parse pkey"); -+ -+ type = EVP_PKEY_base_id(pkey); -+ if (type != EVP_PKEY_DH) { -+ EVP_PKEY_free(pkey); -+ rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type)); - } -- if (!EVP_PKEY_assign_DH(pkey, dh)) { -- DH_free(dh); -- ossl_raise(eDHError, NULL); -+ RTYPEDDATA_DATA(self) = pkey; -+ return self; -+ -+ legacy: -+ BIO_free(in); -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { -+ EVP_PKEY_free(pkey); -+ DH_free(dh); -+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); - } -+ RTYPEDDATA_DATA(self) = pkey; - return self; - } - -@@ -110,15 +133,14 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) - DH *dh, *dh_other; - const BIGNUM *pub, *priv; - -- GetPKey(self, pkey); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) -- ossl_raise(eDHError, "DH already initialized"); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - GetDH(other, dh_other); - - dh = DHparams_dup(dh_other); - if (!dh) - ossl_raise(eDHError, "DHparams_dup"); -- EVP_PKEY_assign_DH(pkey, dh); - - DH_get0_key(dh_other, &pub, &priv); - if (pub) { -@@ -133,6 +155,13 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) - DH_set0_key(dh, pub2, priv2); - } - -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { -+ EVP_PKEY_free(pkey); -+ DH_free(dh); -+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - return self; - } - -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index 7af00eeb..15724548 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -83,50 +83,59 @@ VALUE eDSAError; - static VALUE - ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) - { -- EVP_PKEY *pkey, *tmp; -- DSA *dsa = NULL; -- BIO *in; -+ EVP_PKEY *pkey; -+ DSA *dsa; -+ BIO *in = NULL; - VALUE arg, pass; -+ int type; -+ -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - -- GetPKey(self, pkey); - /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); - if (argc == 0) { - dsa = DSA_new(); - if (!dsa) - ossl_raise(eDSAError, "DSA_new"); -+ goto legacy; - } -- else { -- pass = ossl_pem_passwd_value(pass); -- arg = ossl_to_der_if_possible(arg); -- in = ossl_obj2bio(&arg); -- -- tmp = ossl_pkey_read_generic(in, pass); -- if (tmp) { -- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA) -- rb_raise(eDSAError, "incorrect pkey type: %s", -- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -- dsa = EVP_PKEY_get1_DSA(tmp); -- EVP_PKEY_free(tmp); -- } -- if (!dsa) { -- OSSL_BIO_reset(in); --#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ -- (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u)) -- dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); --#undef PEM_read_bio_DSAPublicKey -- } -- BIO_free(in); -- if (!dsa) { -- ossl_clear_error(); -- ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); -- } -- } -- if (!EVP_PKEY_assign_DSA(pkey, dsa)) { -- DSA_free(dsa); -- ossl_raise(eDSAError, NULL); -+ -+ pass = ossl_pem_passwd_value(pass); -+ arg = ossl_to_der_if_possible(arg); -+ in = ossl_obj2bio(&arg); -+ -+ /* DER-encoded DSAPublicKey format isn't supported by the generic routine */ -+ dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey, -+ PEM_STRING_DSA_PUBLIC, -+ in, NULL, NULL, NULL); -+ if (dsa) -+ goto legacy; -+ OSSL_BIO_reset(in); -+ -+ pkey = ossl_pkey_read_generic(in, pass); -+ BIO_free(in); -+ if (!pkey) -+ ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); -+ -+ type = EVP_PKEY_base_id(pkey); -+ if (type != EVP_PKEY_DSA) { -+ EVP_PKEY_free(pkey); -+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); - } -+ RTYPEDDATA_DATA(self) = pkey; -+ return self; - -+ legacy: -+ BIO_free(in); -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) { -+ EVP_PKEY_free(pkey); -+ DSA_free(dsa); -+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - return self; - } - -@@ -136,16 +145,24 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) - EVP_PKEY *pkey; - DSA *dsa, *dsa_new; - -- GetPKey(self, pkey); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) -- ossl_raise(eDSAError, "DSA already initialized"); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - GetDSA(other, dsa); - -- dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa); -+ dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, -+ (d2i_of_void *)d2i_DSAPrivateKey, -+ (char *)dsa); - if (!dsa_new) - ossl_raise(eDSAError, "ASN1_dup"); - -- EVP_PKEY_assign_DSA(pkey, dsa_new); -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) { -+ EVP_PKEY_free(pkey); -+ DSA_free(dsa_new); -+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - - return self; - } -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index db80d112..71e63969 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -114,13 +114,16 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) - VALUE obj; - - obj = rb_obj_alloc(klass); -- GetPKey(obj, pkey); - - ec = ec_key_new_from_group(arg); -- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { -+ EVP_PKEY_free(pkey); - EC_KEY_free(ec); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); - } -+ RTYPEDDATA_DATA(obj) = pkey; -+ - if (!EC_KEY_generate_key(ec)) - ossl_raise(eECError, "EC_KEY_generate_key"); - -@@ -141,51 +144,54 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) - static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; -- EC_KEY *ec = NULL; -+ EC_KEY *ec; -+ BIO *in; - VALUE arg, pass; -+ int type; - -- GetPKey(self, pkey); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) -- ossl_raise(eECError, "EC_KEY already initialized"); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - - rb_scan_args(argc, argv, "02", &arg, &pass); -- - if (NIL_P(arg)) { - if (!(ec = EC_KEY_new())) -- ossl_raise(eECError, NULL); -- } else if (rb_obj_is_kind_of(arg, cEC)) { -- EC_KEY *other_ec = NULL; -+ ossl_raise(eECError, "EC_KEY_new"); -+ goto legacy; -+ } -+ else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { -+ ec = ec_key_new_from_group(arg); -+ goto legacy; -+ } - -- GetEC(arg, other_ec); -- if (!(ec = EC_KEY_dup(other_ec))) -- ossl_raise(eECError, NULL); -- } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { -- ec = ec_key_new_from_group(arg); -- } else { -- BIO *in = ossl_obj2bio(&arg); -- EVP_PKEY *tmp; -- pass = ossl_pem_passwd_value(pass); -- tmp = ossl_pkey_read_generic(in, pass); -- if (tmp) { -- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC) -- rb_raise(eECError, "incorrect pkey type: %s", -- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -- ec = EVP_PKEY_get1_EC_KEY(tmp); -- EVP_PKEY_free(tmp); -- } -- BIO_free(in); -+ pass = ossl_pem_passwd_value(pass); -+ arg = ossl_to_der_if_possible(arg); -+ in = ossl_obj2bio(&arg); - -- if (!ec) { -- ossl_clear_error(); -- ec = ec_key_new_from_group(arg); -- } -+ pkey = ossl_pkey_read_generic(in, pass); -+ BIO_free(in); -+ if (!pkey) { -+ ossl_clear_error(); -+ ec = ec_key_new_from_group(arg); -+ goto legacy; - } - -- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { -- EC_KEY_free(ec); -- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); -+ type = EVP_PKEY_base_id(pkey); -+ if (type != EVP_PKEY_EC) { -+ EVP_PKEY_free(pkey); -+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); - } -+ RTYPEDDATA_DATA(self) = pkey; -+ return self; - -+ legacy: -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { -+ EVP_PKEY_free(pkey); -+ EC_KEY_free(ec); -+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - return self; - } - -@@ -195,18 +201,21 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) - EVP_PKEY *pkey; - EC_KEY *ec, *ec_new; - -- GetPKey(self, pkey); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) -- ossl_raise(eECError, "EC already initialized"); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - GetEC(other, ec); - - ec_new = EC_KEY_dup(ec); - if (!ec_new) - ossl_raise(eECError, "EC_KEY_dup"); -- if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { -- EC_KEY_free(ec_new); -- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); -+ -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) { -+ EC_KEY_free(ec_new); -+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); - } -+ RTYPEDDATA_DATA(self) = pkey; - - return self; - } -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 8ebd3ec5..b8dbc0e1 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -76,51 +76,62 @@ VALUE eRSAError; - static VALUE - ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - { -- EVP_PKEY *pkey, *tmp; -- RSA *rsa = NULL; -- BIO *in; -+ EVP_PKEY *pkey; -+ RSA *rsa; -+ BIO *in = NULL; - VALUE arg, pass; -+ int type; -+ -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - -- GetPKey(self, pkey); - /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); - if (argc == 0) { - rsa = RSA_new(); - if (!rsa) - ossl_raise(eRSAError, "RSA_new"); -+ goto legacy; - } -- else { -- pass = ossl_pem_passwd_value(pass); -- arg = ossl_to_der_if_possible(arg); -- in = ossl_obj2bio(&arg); -- -- tmp = ossl_pkey_read_generic(in, pass); -- if (tmp) { -- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA) -- rb_raise(eRSAError, "incorrect pkey type: %s", -- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -- rsa = EVP_PKEY_get1_RSA(tmp); -- EVP_PKEY_free(tmp); -- } -- if (!rsa) { -- OSSL_BIO_reset(in); -- rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); -- } -- if (!rsa) { -- OSSL_BIO_reset(in); -- rsa = d2i_RSAPublicKey_bio(in, NULL); -- } -- BIO_free(in); -- if (!rsa) { -- ossl_clear_error(); -- ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); -- } -- } -- if (!EVP_PKEY_assign_RSA(pkey, rsa)) { -- RSA_free(rsa); -- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); -+ -+ pass = ossl_pem_passwd_value(pass); -+ arg = ossl_to_der_if_possible(arg); -+ in = ossl_obj2bio(&arg); -+ -+ /* First try RSAPublicKey format */ -+ rsa = d2i_RSAPublicKey_bio(in, NULL); -+ if (rsa) -+ goto legacy; -+ OSSL_BIO_reset(in); -+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); -+ if (rsa) -+ goto legacy; -+ OSSL_BIO_reset(in); -+ -+ /* Use the generic routine */ -+ pkey = ossl_pkey_read_generic(in, pass); -+ BIO_free(in); -+ if (!pkey) -+ ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); -+ -+ type = EVP_PKEY_base_id(pkey); -+ if (type != EVP_PKEY_RSA) { -+ EVP_PKEY_free(pkey); -+ rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); - } -+ RTYPEDDATA_DATA(self) = pkey; -+ return self; - -+ legacy: -+ BIO_free(in); -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) { -+ EVP_PKEY_free(pkey); -+ RSA_free(rsa); -+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - return self; - } - -@@ -130,16 +141,23 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) - EVP_PKEY *pkey; - RSA *rsa, *rsa_new; - -- GetPKey(self, pkey); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) -- ossl_raise(eRSAError, "RSA already initialized"); -+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); -+ if (pkey) -+ rb_raise(rb_eTypeError, "pkey already initialized"); - GetRSA(other, rsa); - -- rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa); -+ rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, -+ (d2i_of_void *)d2i_RSAPrivateKey, -+ (char *)rsa); - if (!rsa_new) - ossl_raise(eRSAError, "ASN1_dup"); - -- EVP_PKEY_assign_RSA(pkey, rsa_new); -+ pkey = EVP_PKEY_new(); -+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) { -+ RSA_free(rsa_new); -+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); -+ } -+ RTYPEDDATA_DATA(self) = pkey; - - return self; - } - diff --git a/ruby-3.1.0-Allow-setting-algorithm-specific-options-in-sign-and-verify.patch b/ruby-3.1.0-Allow-setting-algorithm-specific-options-in-sign-and-verify.patch deleted file mode 100644 index 679411a..0000000 --- a/ruby-3.1.0-Allow-setting-algorithm-specific-options-in-sign-and-verify.patch +++ /dev/null @@ -1,358 +0,0 @@ -From f2cf3afc6fa1e13e960f732c0bc658ad408ee219 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 12 Jun 2020 14:12:59 +0900 -Subject: [PATCH 1/3] pkey: fix potential memory leak in PKey#sign - -Fix potential leak of EVP_MD_CTX object in an error path. This path is -normally unreachable, since the size of a signature generated by any -supported algorithms would not be larger than LONG_MAX. ---- - ext/openssl/ossl_pkey.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index df8b425a0f..7488190e0e 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -777,8 +777,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSign"); - } -- if (siglen > LONG_MAX) -+ if (siglen > LONG_MAX) { -+ EVP_MD_CTX_free(ctx); - rb_raise(ePKeyError, "signature would be too large"); -+ } - sig = ossl_str_new(NULL, (long)siglen, &state); - if (state) { - EVP_MD_CTX_free(ctx); -@@ -799,8 +801,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } -- if (siglen > LONG_MAX) -+ if (siglen > LONG_MAX) { -+ EVP_MD_CTX_free(ctx); - rb_raise(ePKeyError, "signature would be too large"); -+ } - sig = ossl_str_new(NULL, (long)siglen, &state); - if (state) { - EVP_MD_CTX_free(ctx); --- -2.32.0 - - -From 8b30ce20eb9e03180c28288e29a96308e594f860 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 2 Apr 2021 23:58:48 +0900 -Subject: [PATCH 2/3] pkey: prepare pkey_ctx_apply_options() for usage by other - operations - -The routine to apply Hash to EVP_PKEY_CTX_ctrl_str() is currently used -by key generation, but it is useful for other operations too. Let's -change it to a slightly more generic name. ---- - ext/openssl/ossl_pkey.c | 22 ++++++++++++++-------- - 1 file changed, 14 insertions(+), 8 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 7488190e0e..fed4a2b81f 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -198,7 +198,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) - } - - static VALUE --pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) -+pkey_ctx_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) - { - VALUE key = rb_ary_entry(i, 0), value = rb_ary_entry(i, 1); - EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)ctx_v; -@@ -214,15 +214,25 @@ pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) - } - - static VALUE --pkey_gen_apply_options0(VALUE args_v) -+pkey_ctx_apply_options0(VALUE args_v) - { - VALUE *args = (VALUE *)args_v; - - rb_block_call(args[1], rb_intern("each"), 0, NULL, -- pkey_gen_apply_options_i, args[0]); -+ pkey_ctx_apply_options_i, args[0]); - return Qnil; - } - -+static void -+pkey_ctx_apply_options(EVP_PKEY_CTX *ctx, VALUE options, int *state) -+{ -+ VALUE args[2]; -+ args[0] = (VALUE)ctx; -+ args[1] = options; -+ -+ rb_protect(pkey_ctx_apply_options0, (VALUE)args, state); -+} -+ - struct pkey_blocking_generate_arg { - EVP_PKEY_CTX *ctx; - EVP_PKEY *pkey; -@@ -330,11 +340,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) - } - - if (!NIL_P(options)) { -- VALUE args[2]; -- -- args[0] = (VALUE)ctx; -- args[1] = options; -- rb_protect(pkey_gen_apply_options0, (VALUE)args, &state); -+ pkey_ctx_apply_options(ctx, options, &state); - if (state) { - EVP_PKEY_CTX_free(ctx); - rb_jump_tag(state); --- -2.32.0 - - -From 4c7b0f91da666961d11908b94520db4e09ce4e67 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 18 Jul 2020 20:40:39 +0900 -Subject: [PATCH 3/3] pkey: allow setting algorithm-specific options in #sign - and #verify - -Similarly to OpenSSL::PKey.generate_key and .generate_parameters, let -OpenSSL::PKey::PKey#sign and #verify take an optional parameter for -specifying control strings for EVP_PKEY_CTX_ctrl_str(). ---- - ext/openssl/ossl_pkey.c | 113 ++++++++++++++++++++++------------ - test/openssl/test_pkey_rsa.rb | 34 +++++----- - 2 files changed, 89 insertions(+), 58 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index fed4a2b81f..22e9f19982 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -739,33 +739,51 @@ ossl_pkey_public_to_pem(VALUE self) - } - - /* -- * call-seq: -- * pkey.sign(digest, data) -> String -+ * call-seq: -+ * pkey.sign(digest, data [, options]) -> string - * -- * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must -- * be provided. The return value is again a String containing the signature. -- * A PKeyError is raised should errors occur. -- * Any previous state of the Digest instance is irrelevant to the signature -- * outcome, the digest instance is reset to its initial state during the -- * operation. -+ * Hashes and signs the +data+ using a message digest algorithm +digest+ and -+ * a private key +pkey+. - * -- * == Example -- * data = 'Sign me!' -- * digest = OpenSSL::Digest.new('SHA256') -- * pkey = OpenSSL::PKey::RSA.new(2048) -- * signature = pkey.sign(digest, data) -+ * See #verify for the verification operation. -+ * -+ * See also the man page EVP_DigestSign(3). -+ * -+ * +digest+:: -+ * A String that represents the message digest algorithm name, or +nil+ -+ * if the PKey type requires no digest algorithm. -+ * For backwards compatibility, this can be an instance of OpenSSL::Digest. -+ * Its state will not affect the signature. -+ * +data+:: -+ * A String. The data to be hashed and signed. -+ * +options+:: -+ * A Hash that contains algorithm specific control operations to \OpenSSL. -+ * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. -+ * +options+ parameter was added in version 2.3. -+ * -+ * Example: -+ * data = "Sign me!" -+ * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) -+ * signopts = { rsa_padding_mode: "pss" } -+ * signature = pkey.sign("SHA256", data, signopts) -+ * -+ * # Creates a copy of the RSA key pkey, but without the private components -+ * pub_key = pkey.public_key -+ * puts pub_key.verify("SHA256", signature, data, signopts) # => true - */ - static VALUE --ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) -+ossl_pkey_sign(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; -+ VALUE digest, data, options, sig; - const EVP_MD *md = NULL; - EVP_MD_CTX *ctx; -+ EVP_PKEY_CTX *pctx; - size_t siglen; - int state; -- VALUE sig; - - pkey = GetPrivPKeyPtr(self); -+ rb_scan_args(argc, argv, "21", &digest, &data, &options); - if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); - StringValue(data); -@@ -773,10 +791,17 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - ctx = EVP_MD_CTX_new(); - if (!ctx) - ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -- if (EVP_DigestSignInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { -+ if (EVP_DigestSignInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignInit"); - } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(pctx, options, &state); -+ if (state) { -+ EVP_MD_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } - #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) - if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), - RSTRING_LEN(data)) < 1) { -@@ -828,35 +853,40 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) - } - - /* -- * call-seq: -- * pkey.verify(digest, signature, data) -> String -+ * call-seq: -+ * pkey.verify(digest, signature, data [, options]) -> true or false - * -- * To verify the String _signature_, _digest_, an instance of -- * OpenSSL::Digest, must be provided to re-compute the message digest of the -- * original _data_, also a String. The return value is +true+ if the -- * signature is valid, +false+ otherwise. A PKeyError is raised should errors -- * occur. -- * Any previous state of the Digest instance is irrelevant to the validation -- * outcome, the digest instance is reset to its initial state during the -- * operation. -+ * Verifies the +signature+ for the +data+ using a message digest algorithm -+ * +digest+ and a public key +pkey+. - * -- * == Example -- * data = 'Sign me!' -- * digest = OpenSSL::Digest.new('SHA256') -- * pkey = OpenSSL::PKey::RSA.new(2048) -- * signature = pkey.sign(digest, data) -- * pub_key = pkey.public_key -- * puts pub_key.verify(digest, signature, data) # => true -+ * Returns +true+ if the signature is successfully verified, +false+ otherwise. -+ * The caller must check the return value. -+ * -+ * See #sign for the signing operation and an example. -+ * -+ * See also the man page EVP_DigestVerify(3). -+ * -+ * +digest+:: -+ * See #sign. -+ * +signature+:: -+ * A String containing the signature to be verified. -+ * +data+:: -+ * See #sign. -+ * +options+:: -+ * See #sign. +options+ parameter was added in version 2.3. - */ - static VALUE --ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) -+ossl_pkey_verify(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; -+ VALUE digest, sig, data, options; - const EVP_MD *md = NULL; - EVP_MD_CTX *ctx; -- int ret; -+ EVP_PKEY_CTX *pctx; -+ int state, ret; - - GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); - ossl_pkey_check_public_key(pkey); - if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); -@@ -866,10 +896,17 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) - ctx = EVP_MD_CTX_new(); - if (!ctx) - ossl_raise(ePKeyError, "EVP_MD_CTX_new"); -- if (EVP_DigestVerifyInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { -+ if (EVP_DigestVerifyInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); - } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(pctx, options, &state); -+ if (state) { -+ EVP_MD_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } - #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) - ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), - RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), -@@ -1042,8 +1079,8 @@ Init_ossl_pkey(void) - rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); - rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); - -- rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); -- rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); -+ rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); -+ rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); - rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); - - id_private_q = rb_intern("private?"); -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index 88164c3b52..d1e68dbc9f 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -117,27 +117,21 @@ def test_sign_verify - assert_equal false, rsa1024.verify("SHA256", signature1, data) - end - -- def test_digest_state_irrelevant_sign -+ def test_sign_verify_options - key = Fixtures.pkey("rsa1024") -- digest1 = OpenSSL::Digest.new('SHA1') -- digest2 = OpenSSL::Digest.new('SHA1') -- data = 'Sign me!' -- digest1 << 'Change state of digest1' -- sig1 = key.sign(digest1, data) -- sig2 = key.sign(digest2, data) -- assert_equal(sig1, sig2) -- end -- -- def test_digest_state_irrelevant_verify -- key = Fixtures.pkey("rsa1024") -- digest1 = OpenSSL::Digest.new('SHA1') -- digest2 = OpenSSL::Digest.new('SHA1') -- data = 'Sign me!' -- sig = key.sign(digest1, data) -- digest1.reset -- digest1 << 'Change state of digest1' -- assert(key.verify(digest1, sig, data)) -- assert(key.verify(digest2, sig, data)) -+ data = "Sign me!" -+ pssopts = { -+ "rsa_padding_mode" => "pss", -+ "rsa_pss_saltlen" => 20, -+ "rsa_mgf1_md" => "SHA1" -+ } -+ sig_pss = key.sign("SHA256", data, pssopts) -+ assert_equal 128, sig_pss.bytesize -+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts) -+ assert_equal true, key.verify_pss("SHA256", sig_pss, data, -+ salt_length: 20, mgf1_hash: "SHA1") -+ # Defaults to PKCS #1 v1.5 padding => verification failure -+ assert_equal false, key.verify("SHA256", sig_pss, data) - end - - def test_verify_empty_rsa --- -2.32.0 - diff --git a/ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch b/ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch deleted file mode 100644 index d8f936e..0000000 --- a/ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch +++ /dev/null @@ -1,719 +0,0 @@ -From 46ca47060ca8ef3419ec36c2326a81b442d9b43b Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 12 Dec 2021 01:25:20 +0900 -Subject: [PATCH 1/5] pkey/dh: avoid using DH#set_key in DH#compute_key - -DH#set_key will not work on OpenSSL 3.0 because keys are immutable. -For now, let's reimplement DH#compute_key by manually constructing a -DER-encoded SubjectPublicKeyInfo structure and feeding it to -OpenSSL::PKey.read. - -Eventually, we should implement a new method around EVP_PKEY_fromdata() -and use it instead. ---- - ext/openssl/lib/openssl/pkey.rb | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index f6bf5892..5864faa9 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -47,9 +47,19 @@ def public_key - # * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by - # DH#public_key as that contains the DH parameters only. - def compute_key(pub_bn) -- peer = dup -- peer.set_key(pub_bn, nil) -- derive(peer) -+ # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very -+ # inefficient -+ obj = OpenSSL::ASN1.Sequence([ -+ OpenSSL::ASN1.Sequence([ -+ OpenSSL::ASN1.ObjectId("dhKeyAgreement"), -+ OpenSSL::ASN1.Sequence([ -+ OpenSSL::ASN1.Integer(p), -+ OpenSSL::ASN1.Integer(g), -+ ]), -+ ]), -+ OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der), -+ ]) -+ derive(OpenSSL::PKey.read(obj.to_der)) - end - - # :call-seq: - -From fc9aabc18df3c189cc6a76a1470ca908c4f16480 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 17 Dec 2021 02:22:25 +0900 -Subject: [PATCH 2/5] pkey/ec: avoid using EC#public_key= in EC#dh_compute_key - -Similarly to DH#compute_key, work around it by constructing a -SubjectPublicKeyInfo. This should be considered as a temporary -implementation. ---- - ext/openssl/lib/openssl/pkey.rb | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 5864faa9..ba04cf4b 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -259,9 +259,14 @@ def dsa_verify_asn1(data, sig) - # This method is provided for backwards compatibility, and calls #derive - # internally. - def dh_compute_key(pubkey) -- peer = OpenSSL::PKey::EC.new(group) -- peer.public_key = pubkey -- derive(peer) -+ obj = OpenSSL::ASN1.Sequence([ -+ OpenSSL::ASN1.Sequence([ -+ OpenSSL::ASN1.ObjectId("id-ecPublicKey"), -+ group.to_der, -+ ]), -+ OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)), -+ ]) -+ derive(OpenSSL::PKey.read(obj.to_der)) - end - end - - -From 8ee6a582c7e4614eec4f5ca5ab59898fbcb50d2a Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 22 Oct 2021 16:24:07 +0900 -Subject: [PATCH 3/5] 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. ---- - 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 ba04cf4b..c3e06290 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -71,14 +71,29 @@ def compute_key(pub_bn) - # called first in order to generate the per-session keys before performing - # the actual key exchange. - # -+ # Deprecated in version 3.0. 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 04c11b2157..e70d60ed19 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -58,15 +58,16 @@ VALUE eDHError; - * - * 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 757704ca..ac11af38 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -26,14 +26,19 @@ def test_new_break - 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 @@ def test_public_key - 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") - -From 5e2e66cce870ea86001dbb0eaa3092badfd37994 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 17 Dec 2021 02:21:42 +0900 -Subject: [PATCH 4/5] pkey/ec: deprecate OpenSSL::PKey::EC#generate_key! - -OpenSSL::PKey::EC#generate_key! will not work on OpenSSL 3.0 because -keys are made immutable. Users should use OpenSSL::PKey.generate_key -instead. ---- - ext/openssl/ossl_pkey_ec.c | 4 ++++ - test/openssl/test_pkey_ec.rb | 21 +++++++++++++-------- - 2 files changed, 17 insertions(+), 8 deletions(-) - -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index db80d112..398a550a 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -442,6 +442,9 @@ ossl_ec_key_to_der(VALUE self) - */ - static VALUE ossl_ec_key_generate_key(VALUE self) - { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); -+#else - EC_KEY *ec; - - GetEC(self, ec); -@@ -449,6 +452,7 @@ static VALUE ossl_ec_key_generate_key(VALUE self) - ossl_raise(eECError, "EC_KEY_generate_key"); - - return self; -+#endif - } - - /* -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index 3f5958af..33f78a4c 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -13,15 +13,13 @@ def test_ec_key - # FIPS-selftest failure on some environment, so skip for now. - next if ["Oakley", "X25519"].any? { |n| curve_name.start_with?(n) } - -- key = OpenSSL::PKey::EC.new(curve_name) -- key.generate_key! -- -+ key = OpenSSL::PKey::EC.generate(curve_name) - assert_predicate key, :private? - assert_predicate key, :public? - assert_nothing_raised { key.check_key } - end - -- key1 = OpenSSL::PKey::EC.new("prime256v1").generate_key! -+ key1 = OpenSSL::PKey::EC.generate("prime256v1") - - key2 = OpenSSL::PKey::EC.new - key2.group = key1.group -@@ -52,6 +50,13 @@ def test_generate - assert_equal(true, ec.private?) - end - -+ def test_generate_key -+ ec = OpenSSL::PKey::EC.new("prime256v1") -+ assert_equal false, ec.private? -+ ec.generate_key! -+ assert_equal true, ec.private? -+ end if !openssl?(3, 0, 0) -+ - def test_marshal - key = Fixtures.pkey("p256") - deserialized = Marshal.load(Marshal.dump(key)) -@@ -136,7 +141,7 @@ def test_sign_verify_raw - end - - def test_dsa_sign_asn1_FIPS186_3 -- key = OpenSSL::PKey::EC.new("prime256v1").generate_key! -+ key = OpenSSL::PKey::EC.generate("prime256v1") - size = key.group.order.num_bits / 8 + 1 - dgst = (1..size).to_a.pack('C*') - sig = key.dsa_sign_asn1(dgst) -@@ -145,8 +150,8 @@ def test_dsa_sign_asn1_FIPS186_3 - end - - def test_dh_compute_key -- key_a = OpenSSL::PKey::EC.new("prime256v1").generate_key! -- key_b = OpenSSL::PKey::EC.new(key_a.group).generate_key! -+ key_a = OpenSSL::PKey::EC.generate("prime256v1") -+ key_b = OpenSSL::PKey::EC.generate(key_a.group) - - pub_a = key_a.public_key - pub_b = key_b.public_key -@@ -276,7 +281,7 @@ def test_ec_group - - def test_ec_point - group = OpenSSL::PKey::EC::Group.new("prime256v1") -- key = OpenSSL::PKey::EC.new(group).generate_key! -+ key = OpenSSL::PKey::EC.generate(group) - point = key.public_key - - point2 = OpenSSL::PKey::EC::Point.new(group, point.to_bn) - -From 6848d2d969d90e6a400d89848ecec21076b87888 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 21 Sep 2021 18:29:59 +0900 -Subject: [PATCH 5/5] pkey: deprecate PKey#set_* methods - -OpenSSL 3.0 made EVP_PKEY immutable. This means we can only have a const -pointer of the low level struct and the following methods can no longer -be provided when linked against OpenSSL 3.0: - - - OpenSSL::PKey::RSA#set_key - - OpenSSL::PKey::RSA#set_factors - - OpenSSL::PKey::RSA#set_crt_params - - OpenSSL::PKey::DSA#set_pqg - - OpenSSL::PKey::DSA#set_key - - OpenSSL::PKey::DH#set_pqg - - OpenSSL::PKey::DH#set_key - - OpenSSL::PKey::EC#group= - - OpenSSL::PKey::EC#private_key= - - OpenSSL::PKey::EC#public_key= - -There is no direct replacement for this functionality at the moment. -I plan to introduce a wrapper around EVP_PKEY_fromdata(), which takes -all key components at once to construct an EVP_PKEY. ---- - ext/openssl/ossl_pkey.h | 16 +++++++ - ext/openssl/ossl_pkey_ec.c | 12 +++++ - test/openssl/test_pkey_dh.rb | 38 +++++++++++----- - test/openssl/test_pkey_dsa.rb | 8 +++- - test/openssl/test_pkey_ec.rb | 58 ++++++++++++++---------- - test/openssl/test_pkey_rsa.rb | 85 ++++++++++++++++++++++------------- - 6 files changed, 149 insertions(+), 68 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index 4beede22..4536e58e 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -116,6 +116,7 @@ static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ - _type##_get0_##_group(obj, NULL, &bn)) - -+#if !OSSL_OPENSSL_PREREQ(3, 0, 0) - #define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ - /* \ - * call-seq: \ -@@ -173,6 +174,21 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ - } \ - return self; \ - } -+#else -+#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ -+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ -+{ \ -+ rb_raise(ePKeyError, \ -+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ -+} -+ -+#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ -+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ -+{ \ -+ rb_raise(ePKeyError, \ -+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ -+} -+#endif - - #define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \ - /* \ -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index 398a550a..7a6ed1c9 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -251,6 +251,9 @@ ossl_ec_key_get_group(VALUE self) - static VALUE - ossl_ec_key_set_group(VALUE self, VALUE group_v) - { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); -+#else - EC_KEY *ec; - EC_GROUP *group; - -@@ -261,6 +264,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) - ossl_raise(eECError, "EC_KEY_set_group"); - - return group_v; -+#endif - } - - /* -@@ -289,6 +293,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self) - */ - static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) - { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); -+#else - EC_KEY *ec; - BIGNUM *bn = NULL; - -@@ -307,6 +314,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) - } - - return private_key; -+#endif - } - - /* -@@ -335,6 +343,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self) - */ - static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) - { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); -+#else - EC_KEY *ec; - EC_POINT *point = NULL; - -@@ -353,6 +364,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) - } - - return public_key; -+#endif - } - - /* -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index ac11af38..161af189 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -107,13 +107,32 @@ def test_params_ok? - end - - def test_dup -- dh = Fixtures.pkey("dh1024") -- dh2 = dh.dup -- assert_equal dh.to_der, dh2.to_der # params -- assert_equal_params dh, dh2 # keys -- dh2.set_pqg(dh2.p + 1, nil, dh2.g) -- assert_not_equal dh2.p, dh.p -- assert_equal dh2.g, dh.g -+ # Parameters only -+ dh1 = Fixtures.pkey("dh1024") -+ dh2 = dh1.dup -+ assert_equal dh1.to_der, dh2.to_der -+ assert_not_equal nil, dh1.p -+ assert_not_equal nil, dh1.g -+ assert_equal [dh1.p, dh1.g], [dh2.p, dh2.g] -+ assert_equal nil, dh1.pub_key -+ assert_equal nil, dh1.priv_key -+ assert_equal [dh1.pub_key, dh1.priv_key], [dh2.pub_key, dh2.priv_key] -+ -+ # PKey is immutable in OpenSSL >= 3.0 -+ if !openssl?(3, 0, 0) -+ dh2.set_pqg(dh2.p + 1, nil, dh2.g) -+ assert_not_equal dh2.p, dh1.p -+ end -+ -+ # With a key pair -+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024")) -+ dh4 = dh3.dup -+ assert_equal dh3.to_der, dh4.to_der -+ assert_equal dh1.to_der, dh4.to_der # encodes parameters only -+ assert_equal [dh1.p, dh1.g], [dh4.p, dh4.g] -+ assert_not_equal nil, dh3.pub_key -+ assert_not_equal nil, dh3.priv_key -+ assert_equal [dh3.pub_key, dh3.priv_key], [dh4.pub_key, dh4.priv_key] - end - - def test_marshal -@@ -125,11 +144,6 @@ def test_marshal - - private - -- def assert_equal_params(dh1, dh2) -- assert_equal(dh1.g, dh2.g) -- assert_equal(dh1.p, dh2.p) -- end -- - def assert_no_key(dh) - assert_equal(false, dh.public?) - assert_equal(false, dh.private?) -diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb -index 0994607f..726b7dbf 100644 ---- a/test/openssl/test_pkey_dsa.rb -+++ b/test/openssl/test_pkey_dsa.rb -@@ -208,8 +208,12 @@ def test_dup - key = Fixtures.pkey("dsa1024") - key2 = key.dup - assert_equal key.params, key2.params -- key2.set_pqg(key2.p + 1, key2.q, key2.g) -- assert_not_equal key.params, key2.params -+ -+ # PKey is immutable in OpenSSL >= 3.0 -+ if !openssl?(3, 0, 0) -+ key2.set_pqg(key2.p + 1, key2.q, key2.g) -+ assert_not_equal key.params, key2.params -+ end - end - - def test_marshal -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index 33f78a4c..ffe5a94e 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -21,11 +21,15 @@ def test_ec_key - - key1 = OpenSSL::PKey::EC.generate("prime256v1") - -- key2 = OpenSSL::PKey::EC.new -- key2.group = key1.group -- key2.private_key = key1.private_key -- key2.public_key = key1.public_key -- assert_equal key1.to_der, key2.to_der -+ # PKey is immutable in OpenSSL >= 3.0; constructing an empty EC object is -+ # deprecated -+ if !openssl?(3, 0, 0) -+ key2 = OpenSSL::PKey::EC.new -+ key2.group = key1.group -+ key2.private_key = key1.private_key -+ key2.public_key = key1.public_key -+ assert_equal key1.to_der, key2.to_der -+ end - - key3 = OpenSSL::PKey::EC.new(key1) - assert_equal key1.to_der, key3.to_der -@@ -35,10 +39,14 @@ def test_ec_key - - key5 = key1.dup - assert_equal key1.to_der, key5.to_der -- key_tmp = OpenSSL::PKey::EC.new("prime256v1").generate_key! -- key5.private_key = key_tmp.private_key -- key5.public_key = key_tmp.public_key -- assert_not_equal key1.to_der, key5.to_der -+ -+ # PKey is immutable in OpenSSL >= 3.0; EC object should not be modified -+ if !openssl?(3, 0, 0) -+ key_tmp = OpenSSL::PKey::EC.generate("prime256v1") -+ key5.private_key = key_tmp.private_key -+ key5.public_key = key_tmp.public_key -+ assert_not_equal key1.to_der, key5.to_der -+ end - end - - def test_generate -@@ -65,22 +73,26 @@ def test_marshal - end - - def test_check_key -- key = OpenSSL::PKey::EC.new("prime256v1").generate_key! -- assert_equal(true, key.check_key) -- assert_equal(true, key.private?) -- assert_equal(true, key.public?) -- key2 = OpenSSL::PKey::EC.new(key.group) -- assert_equal(false, key2.private?) -- assert_equal(false, key2.public?) -- key2.public_key = key.public_key -- assert_equal(false, key2.private?) -- assert_equal(true, key2.public?) -- key2.private_key = key.private_key -+ key0 = Fixtures.pkey("p256") -+ assert_equal(true, key0.check_key) -+ assert_equal(true, key0.private?) -+ assert_equal(true, key0.public?) -+ -+ key1 = OpenSSL::PKey.read(key0.public_to_der) -+ assert_equal(true, key1.check_key) -+ assert_equal(false, key1.private?) -+ assert_equal(true, key1.public?) -+ -+ key2 = OpenSSL::PKey.read(key0.private_to_der) - assert_equal(true, key2.private?) - assert_equal(true, key2.public?) - assert_equal(true, key2.check_key) -- key2.private_key += 1 -- assert_raise(OpenSSL::PKey::ECError) { key2.check_key } -+ -+ # EC#private_key= is deprecated in 3.0 and won't work on OpenSSL 3.0 -+ if !openssl?(3, 0, 0) -+ key2.private_key += 1 -+ assert_raise(OpenSSL::PKey::ECError) { key2.check_key } -+ end - end - - def test_sign_verify -@@ -112,7 +124,7 @@ def test_derive_key - assert_equal [zIUT].pack("H*"), a.derive(b) - - assert_equal a.derive(b), a.dh_compute_key(b.public_key) -- end -+ end if !openssl?(3, 0, 0) # TODO: Test it without using #private_key= - - def test_sign_verify_raw - key = Fixtures.pkey("p256") -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index dbe87ba4..1c7f9ccf 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -31,15 +31,18 @@ def test_private - assert(!key4.private?) - rsa1024 = Fixtures.pkey("rsa1024") - -- # Generated by RSA#set_key -- key5 = OpenSSL::PKey::RSA.new -- key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -- assert(key5.private?) -- -- # Generated by RSA#set_key, without d -- key6 = OpenSSL::PKey::RSA.new -- key6.set_key(rsa1024.n, rsa1024.e, nil) -- assert(!key6.private?) -+ if !openssl?(3, 0, 0) -+ key = OpenSSL::PKey::RSA.new -+ # Generated by RSA#set_key -+ key5 = OpenSSL::PKey::RSA.new -+ key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -+ assert(key5.private?) -+ -+ # Generated by RSA#set_key, without d -+ key6 = OpenSSL::PKey::RSA.new -+ key6.set_key(rsa1024.n, rsa1024.e, nil) -+ assert(!key6.private?) -+ end - end - - def test_new -@@ -235,36 +238,52 @@ def test_encrypt_decrypt_legacy - - def test_export - rsa1024 = Fixtures.pkey("rsa1024") -- key = OpenSSL::PKey::RSA.new - -- # key has only n, e and d -- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -- assert_equal rsa1024.public_key.export, key.export -+ pub = OpenSSL::PKey.read(rsa1024.public_to_der) -+ assert_not_equal rsa1024.export, pub.export -+ assert_equal rsa1024.public_to_pem, pub.export -+ -+ # PKey is immutable in OpenSSL >= 3.0 -+ if !openssl?(3, 0, 0) -+ key = OpenSSL::PKey::RSA.new - -- # key has only n, e, d, p and q -- key.set_factors(rsa1024.p, rsa1024.q) -- assert_equal rsa1024.public_key.export, key.export -+ # key has only n, e and d -+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -+ assert_equal rsa1024.public_key.export, key.export - -- # key has n, e, d, p, q, dmp1, dmq1 and iqmp -- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) -- assert_equal rsa1024.export, key.export -+ # key has only n, e, d, p and q -+ key.set_factors(rsa1024.p, rsa1024.q) -+ assert_equal rsa1024.public_key.export, key.export -+ -+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp -+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) -+ assert_equal rsa1024.export, key.export -+ end - end - - def test_to_der - rsa1024 = Fixtures.pkey("rsa1024") -- key = OpenSSL::PKey::RSA.new - -- # key has only n, e and d -- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -- assert_equal rsa1024.public_key.to_der, key.to_der -+ pub = OpenSSL::PKey.read(rsa1024.public_to_der) -+ assert_not_equal rsa1024.to_der, pub.to_der -+ assert_equal rsa1024.public_to_der, pub.to_der - -- # key has only n, e, d, p and q -- key.set_factors(rsa1024.p, rsa1024.q) -- assert_equal rsa1024.public_key.to_der, key.to_der -+ # PKey is immutable in OpenSSL >= 3.0 -+ if !openssl?(3, 0, 0) -+ key = OpenSSL::PKey::RSA.new - -- # key has n, e, d, p, q, dmp1, dmq1 and iqmp -- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) -- assert_equal rsa1024.to_der, key.to_der -+ # key has only n, e and d -+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) -+ assert_equal rsa1024.public_key.to_der, key.to_der -+ -+ # key has only n, e, d, p and q -+ key.set_factors(rsa1024.p, rsa1024.q) -+ assert_equal rsa1024.public_key.to_der, key.to_der -+ -+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp -+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) -+ assert_equal rsa1024.to_der, key.to_der -+ end - end - - def test_RSAPrivateKey -@@ -501,8 +520,12 @@ def test_dup - key = Fixtures.pkey("rsa1024") - key2 = key.dup - assert_equal key.params, key2.params -- key2.set_key(key2.n, 3, key2.d) -- assert_not_equal key.params, key2.params -+ -+ # PKey is immutable in OpenSSL >= 3.0 -+ if !openssl?(3, 0, 0) -+ key2.set_key(key2.n, 3, key2.d) -+ assert_not_equal key.params, key2.params -+ end - end - - def test_marshal diff --git a/ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch b/ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch deleted file mode 100644 index 2b640ea..0000000 --- a/ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 47975ece4096cdab16b3f200f93ea2377dfb41ac Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 31 May 2021 14:17:21 +0900 -Subject: [PATCH] test/openssl/test_pkey_rsa: disable test_no_private_exp on - OpenSSL 3.0 - -OpenSSL::PKey::RSA#set_key does not exist when built with OpenSSL 3.0, -so it is not possible to create an RSA object with incomplete state. - -https://github.com/ruby/openssl/commit/ca03c9c070 ---- - test/openssl/test_pkey_rsa.rb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index 4548bdb2cfa6..dbe87ba4c1b0 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -11,7 +11,7 @@ def test_no_private_exp - key.set_factors(rsa.p, rsa.q) - assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt("foo") } - assert_raise(OpenSSL::PKey::RSAError){ key.private_decrypt("foo") } -- end -+ end if !openssl?(3, 0, 0) # Impossible state in OpenSSL 3.0 - - def test_private - # Generated by key size and public exponent diff --git a/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch b/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch deleted file mode 100644 index ae8f722..0000000 --- a/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001 -From: Nobuyoshi Nakada -Date: Thu, 5 Aug 2021 20:09:25 +0900 -Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062] - ---- - vm_eval.c | 4 +++- - vm_insnhelper.c | 7 +++++-- - vm_method.c | 41 ++++++++++++++++++++++++++--------------- - 3 files changed, 34 insertions(+), 18 deletions(-) - -diff --git a/vm_eval.c b/vm_eval.c -index 6d4b5c3c0b28..7ce9f157e671 100644 ---- a/vm_eval.c -+++ b/vm_eval.c -@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme) - { - struct rb_class_cc_entries *ccs; - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); -+ VALUE ccs_data; - -- if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) { -+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { - // ok -+ ccs = (struct rb_class_cc_entries *)ccs_data; - } - else { - ccs = vm_ccs_create(klass, cme); -diff --git a/vm_insnhelper.c b/vm_insnhelper.c -index 14928b2afe8e..e186376b24d7 100644 ---- a/vm_insnhelper.c -+++ b/vm_insnhelper.c -@@ -1637,9 +1637,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) - const ID mid = vm_ci_mid(ci); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); - struct rb_class_cc_entries *ccs = NULL; -+ VALUE ccs_data; - - if (cc_tbl) { -- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { -+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { -+ ccs = (struct rb_class_cc_entries *)ccs_data; - const int ccs_len = ccs->len; - VM_ASSERT(vm_ccs_verify(ccs, mid, klass)); - -@@ -1706,8 +1708,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) - if (ccs == NULL) { - VM_ASSERT(cc_tbl != NULL); - -- if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) { -+ if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) { - // rb_callable_method_entry() prepares ccs. -+ ccs = (struct rb_class_cc_entries *)ccs_data; - } - else { - // TODO: required? -diff --git a/vm_method.c b/vm_method.c -index 016dba1dbb18..1fd0bd57f7ca 100644 ---- a/vm_method.c -+++ b/vm_method.c -@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid) - { - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); - if (cc_tbl) { -- const struct rb_class_cc_entries *ccs; -+ VALUE ccs; - if (target_mid) { -- if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) { -+ if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) { - fprintf(stderr, " [CCTB] %p\n", (void *)cc_tbl); -- vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL); -+ vm_ccs_dump_i(target_mid, ccs, NULL); - } - } - else { -@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid) - fprintf(stderr, "# vm_mtbl\n"); - while (klass) { - rp_m(" -> ", klass); -- rb_method_entry_t *me; -+ VALUE me; - - if (RCLASS_M_TBL(klass)) { - if (target_mid != 0) { -- if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) { -+ if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) { - rp_m(" [MTBL] ", me); - } - } -@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid) - } - if (RCLASS_CALLABLE_M_TBL(klass)) { - if (target_mid != 0) { -- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) { -+ if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) { - rp_m(" [CM**] ", me); - } - } -@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) - // check only current class - - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); -- struct rb_class_cc_entries *ccs; -+ VALUE ccs_data; - - // invalidate CCs -- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { -+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { -+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; - rb_vm_ccs_free(ccs); - rb_id_table_delete(cc_tbl, mid); - RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs); -@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) - } - else { - rb_vm_t *vm = GET_VM(); -- if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { -+ VALUE cme_data = (VALUE) cme; -+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { - rb_id_table_delete(vm->negative_cme_table, mid); -- vm_me_invalidate_cache((rb_callable_method_entry_t *)cme); -+ vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data); - - RB_DEBUG_COUNTER_INC(cc_invalidate_negative); - } -@@ -1023,6 +1025,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ - { - struct rb_id_table *mtbl; - const rb_callable_method_entry_t *cme; -+ VALUE cme_data; - - if (me) { - if (me->defined_class == 0) { -@@ -1032,7 +1035,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ - - mtbl = RCLASS_CALLABLE_M_TBL(defined_class); - -- if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) { -+ if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) { -+ cme = (rb_callable_method_entry_t *)cme_data; - RB_DEBUG_COUNTER_INC(mc_cme_complement_hit); - VM_ASSERT(callable_method_entry_p(cme)); - VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme)); -@@ -1076,9 +1080,10 @@ cached_callable_method_entry(VALUE klass, ID mid) - ASSERT_vm_locking(); - - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); -- struct rb_class_cc_entries *ccs; -+ VALUE ccs_data; - -- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { -+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { -+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; - VM_ASSERT(vm_ccs_p(ccs)); - - if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) { -@@ -1104,12 +1109,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ - - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); - struct rb_class_cc_entries *ccs; -+ VALUE ccs_data; - - if (!cc_tbl) { - cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); - } - -- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { -+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { -+ ccs = (struct rb_class_cc_entries *)ccs_data; - VM_ASSERT(ccs->cme == cme); - } - else { -@@ -1123,8 +1130,12 @@ negative_cme(ID mid) - { - rb_vm_t *vm = GET_VM(); - const rb_callable_method_entry_t *cme; -+ VALUE cme_data; - -- if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { -+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { -+ cme = (rb_callable_method_entry_t *)cme_data; -+ } -+ else { - cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL); - rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme); - } diff --git a/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch b/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch deleted file mode 100644 index 86f534d..0000000 --- a/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 72317b333b85eed483ad00bcd4f40944019a7c13 Mon Sep 17 00:00:00 2001 -From: "xtkoba+ruby@gmail.com" -Date: Fri, 13 Aug 2021 13:45:53 +0000 -Subject: [PATCH] Ignore `DW_FORM_ref_addr` [Bug #17052] - -Ignore `DW_FORM_ref_addr` form and other forms that are not supposed -to be used currently. ---- - addr2line.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/addr2line.c b/addr2line.c -index fed1a8da84e5..92c6da5e3bea 100644 ---- a/addr2line.c -+++ b/addr2line.c -@@ -1593,14 +1593,31 @@ di_read_cu(DebugInfoReader *reader) - } - - static void --read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line) -+read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line) - { - char *p = reader->p; - char *q = reader->q; - int level = reader->level; - DIE die; - -- reader->p = reader->current_cu + abstract_origin; -+ switch (form) { -+ case DW_FORM_ref1: -+ case DW_FORM_ref2: -+ case DW_FORM_ref4: -+ case DW_FORM_ref8: -+ case DW_FORM_ref_udata: -+ reader->p = reader->current_cu + abstract_origin; -+ break; -+ case DW_FORM_ref_addr: -+ goto finish; /* not supported yet */ -+ case DW_FORM_ref_sig8: -+ goto finish; /* not supported yet */ -+ case DW_FORM_ref_sup4: -+ case DW_FORM_ref_sup8: -+ goto finish; /* not supported yet */ -+ default: -+ goto finish; -+ } - if (!di_read_die(reader, &die)) goto finish; - - /* enumerate abbrev */ -@@ -1665,7 +1682,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, - /* 1 or 3 */ - break; /* goto skip_die; */ - case DW_AT_abstract_origin: -- read_abstract_origin(reader, v.as.uint64, &line); -+ read_abstract_origin(reader, v.form, v.as.uint64, &line); - break; /* goto skip_die; */ - } - } diff --git a/ruby-3.1.0-Implement-PKey-encrypt-decrypt-sign_raw-verify_raw-and-verify_recover.patch b/ruby-3.1.0-Implement-PKey-encrypt-decrypt-sign_raw-verify_raw-and-verify_recover.patch deleted file mode 100644 index a558cec..0000000 --- a/ruby-3.1.0-Implement-PKey-encrypt-decrypt-sign_raw-verify_raw-and-verify_recover.patch +++ /dev/null @@ -1,1319 +0,0 @@ -From 3e6cd88c621d8834712d2279f925b9af83c2bb34 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 18 May 2020 20:06:16 +0900 -Subject: [PATCH 1/6] pkey: implement PKey#encrypt and #decrypt - -Support public key encryption and decryption operations using the EVP -API. ---- - ext/openssl/ossl_pkey.c | 141 ++++++++++++++++++++++++++++++++++ - test/openssl/test_pkey_rsa.rb | 34 ++++++++ - 2 files changed, 175 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 21cd4b2cda..baf8ce9f20 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -986,6 +986,145 @@ ossl_pkey_derive(int argc, VALUE *argv, VALUE self) - return str; - } - -+/* -+ * call-seq: -+ * pkey.encrypt(data [, options]) -> string -+ * -+ * Performs a public key encryption operation using +pkey+. -+ * -+ * See #decrypt for the reverse operation. -+ * -+ * Added in version 3.0. See also the man page EVP_PKEY_encrypt(3). -+ * -+ * +data+:: -+ * A String to be encrypted. -+ * +options+:: -+ * A Hash that contains algorithm specific control operations to \OpenSSL. -+ * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. -+ * -+ * Example: -+ * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) -+ * data = "secret data" -+ * encrypted = pkey.encrypt(data, rsa_padding_mode: "oaep") -+ * decrypted = pkey.decrypt(data, rsa_padding_mode: "oaep") -+ * p decrypted #=> "secret data" -+ */ -+static VALUE -+ossl_pkey_encrypt(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey; -+ EVP_PKEY_CTX *ctx; -+ VALUE data, options, str; -+ size_t outlen; -+ int state; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "11", &data, &options); -+ StringValue(data); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_encrypt_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_encrypt_init"); -+ } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(ctx, options, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ if (EVP_PKEY_encrypt(ctx, NULL, &outlen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_encrypt"); -+ } -+ if (outlen > LONG_MAX) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_raise(ePKeyError, "encrypted data would be too large"); -+ } -+ str = ossl_str_new(NULL, (long)outlen, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_PKEY_encrypt(ctx, (unsigned char *)RSTRING_PTR(str), &outlen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_encrypt"); -+ } -+ EVP_PKEY_CTX_free(ctx); -+ rb_str_set_len(str, outlen); -+ return str; -+} -+ -+/* -+ * call-seq: -+ * pkey.decrypt(data [, options]) -> string -+ * -+ * Performs a public key decryption operation using +pkey+. -+ * -+ * See #encrypt for a description of the parameters and an example. -+ * -+ * Added in version 3.0. See also the man page EVP_PKEY_decrypt(3). -+ */ -+static VALUE -+ossl_pkey_decrypt(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey; -+ EVP_PKEY_CTX *ctx; -+ VALUE data, options, str; -+ size_t outlen; -+ int state; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "11", &data, &options); -+ StringValue(data); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_decrypt_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_decrypt_init"); -+ } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(ctx, options, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ if (EVP_PKEY_decrypt(ctx, NULL, &outlen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_decrypt"); -+ } -+ if (outlen > LONG_MAX) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_raise(ePKeyError, "decrypted data would be too large"); -+ } -+ str = ossl_str_new(NULL, (long)outlen, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_PKEY_decrypt(ctx, (unsigned char *)RSTRING_PTR(str), &outlen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_decrypt"); -+ } -+ EVP_PKEY_CTX_free(ctx); -+ rb_str_set_len(str, outlen); -+ return str; -+} -+ - /* - * INIT - */ -@@ -1085,6 +1224,8 @@ Init_ossl_pkey(void) - rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); - rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); - rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); -+ rb_define_method(cPKey, "encrypt", ossl_pkey_encrypt, -1); -+ rb_define_method(cPKey, "decrypt", ossl_pkey_decrypt, -1); - - id_private_q = rb_intern("private?"); - -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index 5f8d04e754..d6bfca3ac5 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -173,6 +173,40 @@ def test_sign_verify_pss - } - end - -+ def test_encrypt_decrypt -+ rsapriv = Fixtures.pkey("rsa-1") -+ rsapub = dup_public(rsapriv) -+ -+ # Defaults to PKCS #1 v1.5 -+ raw = "data" -+ enc = rsapub.encrypt(raw) -+ assert_equal raw, rsapriv.decrypt(enc) -+ -+ # Invalid options -+ assert_raise(OpenSSL::PKey::PKeyError) { -+ rsapub.encrypt(raw, { "nonexistent" => "option" }) -+ } -+ end -+ -+ def test_encrypt_decrypt_legacy -+ rsapriv = Fixtures.pkey("rsa-1") -+ rsapub = dup_public(rsapriv) -+ -+ # Defaults to PKCS #1 v1.5 -+ raw = "data" -+ enc_legacy = rsapub.public_encrypt(raw) -+ assert_equal raw, rsapriv.decrypt(enc_legacy) -+ enc_new = rsapub.encrypt(raw) -+ assert_equal raw, rsapriv.private_decrypt(enc_new) -+ -+ # OAEP with default parameters -+ raw = "data" -+ enc_legacy = rsapub.public_encrypt(raw, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) -+ assert_equal raw, rsapriv.decrypt(enc_legacy, { "rsa_padding_mode" => "oaep" }) -+ enc_new = rsapub.encrypt(raw, { "rsa_padding_mode" => "oaep" }) -+ assert_equal raw, rsapriv.private_decrypt(enc_legacy, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) -+ end -+ - def test_export - rsa1024 = Fixtures.pkey("rsa1024") - key = OpenSSL::PKey::RSA.new --- -2.32.0 - - -From 6f5c75b06967b5b2db1d13646d74310e1cdc563e Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 25 May 2021 18:43:29 +0900 -Subject: [PATCH 2/6] pkey: update version reference in #sign and #verify - documentation - -The next release is decided to be 3.0 rather than 2.3. ---- - ext/openssl/ossl_pkey.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index baf8ce9f20..d08f6f7e60 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -761,7 +761,7 @@ ossl_pkey_public_to_pem(VALUE self) - * +options+:: - * A Hash that contains algorithm specific control operations to \OpenSSL. - * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. -- * +options+ parameter was added in version 2.3. -+ * +options+ parameter was added in version 3.0. - * - * Example: - * data = "Sign me!" -@@ -875,7 +875,7 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self) - * +data+:: - * See #sign. - * +options+:: -- * See #sign. +options+ parameter was added in version 2.3. -+ * See #sign. +options+ parameter was added in version 3.0. - */ - static VALUE - ossl_pkey_verify(int argc, VALUE *argv, VALUE self) --- -2.32.0 - - -From 99fc31a9b4843b7f8923b5ce8b36115b2c66f4db Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 22 May 2020 16:10:35 +0900 -Subject: [PATCH 3/6] pkey: implement PKey#sign_raw, #verify_raw, and - #verify_recover - -Add a variant of PKey#sign and #verify that do not hash the data -automatically. - -Sometimes the caller has the hashed data only, but not the plaintext -to be signed. In that case, users would have to use the low-level API -such as RSA#private_encrypt or #public_decrypt directly. - -OpenSSL 1.0.0 and later supports EVP_PKEY_sign() and EVP_PKEY_verify() -which provide the same functionality as part of the EVP API. This patch -adds wrappers for them. ---- - ext/openssl/ossl_pkey.c | 232 ++++++++++++++++++++++++++++++++++ - test/openssl/test_pkey_dsa.rb | 25 +++- - test/openssl/test_pkey_ec.rb | 21 ++- - test/openssl/test_pkey_rsa.rb | 78 ++++++++---- - 4 files changed, 325 insertions(+), 31 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index d08f6f7e60..ba909c7632 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -935,6 +935,235 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self) - } - } - -+/* -+ * call-seq: -+ * pkey.sign_raw(digest, data [, options]) -> string -+ * -+ * Signs +data+ using a private key +pkey+. Unlike #sign, +data+ will not be -+ * hashed by +digest+ automatically. -+ * -+ * See #verify_raw for the verification operation. -+ * -+ * Added in version 3.0. See also the man page EVP_PKEY_sign(3). -+ * -+ * +digest+:: -+ * A String that represents the message digest algorithm name, or +nil+ -+ * if the PKey type requires no digest algorithm. -+ * Although this method will not hash +data+ with it, this parameter may still -+ * be required depending on the signature algorithm. -+ * +data+:: -+ * A String. The data to be signed. -+ * +options+:: -+ * A Hash that contains algorithm specific control operations to \OpenSSL. -+ * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. -+ * -+ * Example: -+ * data = "Sign me!" -+ * hash = OpenSSL::Digest.digest("SHA256", data) -+ * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) -+ * signopts = { rsa_padding_mode: "pss" } -+ * signature = pkey.sign_raw("SHA256", hash, signopts) -+ * -+ * # Creates a copy of the RSA key pkey, but without the private components -+ * pub_key = pkey.public_key -+ * puts pub_key.verify_raw("SHA256", signature, hash, signopts) # => true -+ */ -+static VALUE -+ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey; -+ VALUE digest, data, options, sig; -+ const EVP_MD *md = NULL; -+ EVP_PKEY_CTX *ctx; -+ size_t outlen; -+ int state; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "21", &digest, &data, &options); -+ if (!NIL_P(digest)) -+ md = ossl_evp_get_digestbyname(digest); -+ StringValue(data); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_sign_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_sign_init"); -+ } -+ if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); -+ } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(ctx, options, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ if (EVP_PKEY_sign(ctx, NULL, &outlen, (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_sign"); -+ } -+ if (outlen > LONG_MAX) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_raise(ePKeyError, "signature would be too large"); -+ } -+ sig = ossl_str_new(NULL, (long)outlen, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_PKEY_sign(ctx, (unsigned char *)RSTRING_PTR(sig), &outlen, -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_sign"); -+ } -+ EVP_PKEY_CTX_free(ctx); -+ rb_str_set_len(sig, outlen); -+ return sig; -+} -+ -+/* -+ * call-seq: -+ * pkey.verify_raw(digest, signature, data [, options]) -> true or false -+ * -+ * Verifies the +signature+ for the +data+ using a public key +pkey+. Unlike -+ * #verify, this method will not hash +data+ with +digest+ automatically. -+ * -+ * Returns +true+ if the signature is successfully verified, +false+ otherwise. -+ * The caller must check the return value. -+ * -+ * See #sign_raw for the signing operation and an example code. -+ * -+ * Added in version 3.0. See also the man page EVP_PKEY_verify(3). -+ * -+ * +signature+:: -+ * A String containing the signature to be verified. -+ */ -+static VALUE -+ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey; -+ VALUE digest, sig, data, options; -+ const EVP_MD *md = NULL; -+ EVP_PKEY_CTX *ctx; -+ int state, ret; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); -+ ossl_pkey_check_public_key(pkey); -+ if (!NIL_P(digest)) -+ md = ossl_evp_get_digestbyname(digest); -+ StringValue(sig); -+ StringValue(data); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_verify_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_verify_init"); -+ } -+ if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); -+ } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(ctx, options, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ ret = EVP_PKEY_verify(ctx, (unsigned char *)RSTRING_PTR(sig), -+ RSTRING_LEN(sig), -+ (unsigned char *)RSTRING_PTR(data), -+ RSTRING_LEN(data)); -+ EVP_PKEY_CTX_free(ctx); -+ if (ret < 0) -+ ossl_raise(ePKeyError, "EVP_PKEY_verify"); -+ -+ if (ret) -+ return Qtrue; -+ else { -+ ossl_clear_error(); -+ return Qfalse; -+ } -+} -+ -+/* -+ * call-seq: -+ * pkey.verify_recover(digest, signature [, options]) -> string -+ * -+ * Recovers the signed data from +signature+ using a public key +pkey+. Not all -+ * signature algorithms support this operation. -+ * -+ * Added in version 3.0. See also the man page EVP_PKEY_verify_recover(3). -+ * -+ * +signature+:: -+ * A String containing the signature to be verified. -+ */ -+static VALUE -+ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self) -+{ -+ EVP_PKEY *pkey; -+ VALUE digest, sig, options, out; -+ const EVP_MD *md = NULL; -+ EVP_PKEY_CTX *ctx; -+ int state; -+ size_t outlen; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "21", &digest, &sig, &options); -+ ossl_pkey_check_public_key(pkey); -+ if (!NIL_P(digest)) -+ md = ossl_evp_get_digestbyname(digest); -+ StringValue(sig); -+ -+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); -+ if (EVP_PKEY_verify_recover_init(ctx) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_verify_recover_init"); -+ } -+ if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); -+ } -+ if (!NIL_P(options)) { -+ pkey_ctx_apply_options(ctx, options, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ } -+ if (EVP_PKEY_verify_recover(ctx, NULL, &outlen, -+ (unsigned char *)RSTRING_PTR(sig), -+ RSTRING_LEN(sig)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_verify_recover"); -+ } -+ out = ossl_str_new(NULL, (long)outlen, &state); -+ if (state) { -+ EVP_PKEY_CTX_free(ctx); -+ rb_jump_tag(state); -+ } -+ if (EVP_PKEY_verify_recover(ctx, (unsigned char *)RSTRING_PTR(out), &outlen, -+ (unsigned char *)RSTRING_PTR(sig), -+ RSTRING_LEN(sig)) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ossl_raise(ePKeyError, "EVP_PKEY_verify_recover"); -+ } -+ EVP_PKEY_CTX_free(ctx); -+ rb_str_set_len(out, outlen); -+ return out; -+} -+ - /* - * call-seq: - * pkey.derive(peer_pkey) -> string -@@ -1223,6 +1452,9 @@ Init_ossl_pkey(void) - - rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); - rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); -+ rb_define_method(cPKey, "sign_raw", ossl_pkey_sign_raw, -1); -+ rb_define_method(cPKey, "verify_raw", ossl_pkey_verify_raw, -1); -+ rb_define_method(cPKey, "verify_recover", ossl_pkey_verify_recover, -1); - rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); - rb_define_method(cPKey, "encrypt", ossl_pkey_encrypt, -1); - rb_define_method(cPKey, "decrypt", ossl_pkey_decrypt, -1); -diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb -index 85bb6ec0ae..147e50176b 100644 ---- a/test/openssl/test_pkey_dsa.rb -+++ b/test/openssl/test_pkey_dsa.rb -@@ -48,12 +48,31 @@ def test_sign_verify - assert_equal false, dsa512.verify("SHA256", signature1, data) - end - -- def test_sys_sign_verify -- key = Fixtures.pkey("dsa256") -+ def test_sign_verify_raw -+ key = Fixtures.pkey("dsa512") - data = 'Sign me!' - digest = OpenSSL::Digest.digest('SHA1', data) -+ -+ invalid_sig = key.sign_raw(nil, digest.succ) -+ malformed_sig = "*" * invalid_sig.bytesize -+ -+ # Sign by #syssign - sig = key.syssign(digest) -- assert(key.sysverify(digest, sig)) -+ assert_equal true, key.sysverify(digest, sig) -+ assert_equal false, key.sysverify(digest, invalid_sig) -+ assert_raise(OpenSSL::PKey::DSAError) { key.sysverify(digest, malformed_sig) } -+ assert_equal true, key.verify_raw(nil, sig, digest) -+ assert_equal false, key.verify_raw(nil, invalid_sig, digest) -+ assert_raise(OpenSSL::PKey::PKeyError) { key.verify_raw(nil, malformed_sig, digest) } -+ -+ # Sign by #sign_raw -+ sig = key.sign_raw(nil, digest) -+ assert_equal true, key.sysverify(digest, sig) -+ assert_equal false, key.sysverify(digest, invalid_sig) -+ assert_raise(OpenSSL::PKey::DSAError) { key.sysverify(digest, malformed_sig) } -+ assert_equal true, key.verify_raw(nil, sig, digest) -+ assert_equal false, key.verify_raw(nil, invalid_sig, digest) -+ assert_raise(OpenSSL::PKey::PKeyError) { key.verify_raw(nil, malformed_sig, digest) } - end - - def test_DSAPrivateKey -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index 95d4338a51..4b6df0290f 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -109,13 +109,30 @@ def test_derive_key - assert_equal a.derive(b), a.dh_compute_key(b.public_key) - end - -- def test_dsa_sign_verify -+ def test_sign_verify_raw -+ key = Fixtures.pkey("p256") - data1 = "foo" - data2 = "bar" -- key = OpenSSL::PKey::EC.new("prime256v1").generate_key! -+ -+ malformed_sig = "*" * 30 -+ -+ # Sign by #dsa_sign_asn1 - sig = key.dsa_sign_asn1(data1) - assert_equal true, key.dsa_verify_asn1(data1, sig) - assert_equal false, key.dsa_verify_asn1(data2, sig) -+ assert_raise(OpenSSL::PKey::ECError) { key.dsa_verify_asn1(data1, malformed_sig) } -+ assert_equal true, key.verify_raw(nil, sig, data1) -+ assert_equal false, key.verify_raw(nil, sig, data2) -+ assert_raise(OpenSSL::PKey::PKeyError) { key.verify_raw(nil, malformed_sig, data1) } -+ -+ # Sign by #sign_raw -+ sig = key.sign_raw(nil, data1) -+ assert_equal true, key.dsa_verify_asn1(data1, sig) -+ assert_equal false, key.dsa_verify_asn1(data2, sig) -+ assert_raise(OpenSSL::PKey::ECError) { key.dsa_verify_asn1(data1, malformed_sig) } -+ assert_equal true, key.verify_raw(nil, sig, data1) -+ assert_equal false, key.verify_raw(nil, sig, data2) -+ assert_raise(OpenSSL::PKey::PKeyError) { key.verify_raw(nil, malformed_sig, data1) } - end - - def test_dsa_sign_asn1_FIPS186_3 -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index d6bfca3ac5..5e127f5407 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -13,32 +13,6 @@ def test_no_private_exp - assert_raise(OpenSSL::PKey::RSAError){ key.private_decrypt("foo") } - end - -- def test_padding -- key = OpenSSL::PKey::RSA.new(512, 3) -- -- # Need right size for raw mode -- plain0 = "x" * (512/8) -- cipher = key.private_encrypt(plain0, OpenSSL::PKey::RSA::NO_PADDING) -- plain1 = key.public_decrypt(cipher, OpenSSL::PKey::RSA::NO_PADDING) -- assert_equal(plain0, plain1) -- -- # Need smaller size for pkcs1 mode -- plain0 = "x" * (512/8 - 11) -- cipher1 = key.private_encrypt(plain0, OpenSSL::PKey::RSA::PKCS1_PADDING) -- plain1 = key.public_decrypt(cipher1, OpenSSL::PKey::RSA::PKCS1_PADDING) -- assert_equal(plain0, plain1) -- -- cipherdef = key.private_encrypt(plain0) # PKCS1_PADDING is default -- plain1 = key.public_decrypt(cipherdef) -- assert_equal(plain0, plain1) -- assert_equal(cipher1, cipherdef) -- -- # Failure cases -- assert_raise(ArgumentError){ key.private_encrypt() } -- assert_raise(ArgumentError){ key.private_encrypt("hi", 1, nil) } -- assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt(plain0, 666) } -- end -- - def test_private - # Generated by key size and public exponent - key = OpenSSL::PKey::RSA.new(512, 3) -@@ -133,6 +107,58 @@ def test_sign_verify_options - assert_equal false, key.verify("SHA256", sig_pss, data) - end - -+ def test_sign_verify_raw -+ key = Fixtures.pkey("rsa-1") -+ data = "Sign me!" -+ hash = OpenSSL::Digest.digest("SHA1", data) -+ signature = key.sign_raw("SHA1", hash) -+ assert_equal true, key.verify_raw("SHA1", signature, hash) -+ assert_equal true, key.verify("SHA1", signature, data) -+ -+ # Too long data -+ assert_raise(OpenSSL::PKey::PKeyError) { -+ key.sign_raw("SHA1", "x" * (key.n.num_bytes + 1)) -+ } -+ -+ # With options -+ pssopts = { -+ "rsa_padding_mode" => "pss", -+ "rsa_pss_saltlen" => 20, -+ "rsa_mgf1_md" => "SHA256" -+ } -+ sig_pss = key.sign_raw("SHA1", hash, pssopts) -+ assert_equal true, key.verify("SHA1", sig_pss, data, pssopts) -+ assert_equal true, key.verify_raw("SHA1", sig_pss, hash, pssopts) -+ end -+ -+ def test_sign_verify_raw_legacy -+ key = Fixtures.pkey("rsa-1") -+ bits = key.n.num_bits -+ -+ # Need right size for raw mode -+ plain0 = "x" * (bits/8) -+ cipher = key.private_encrypt(plain0, OpenSSL::PKey::RSA::NO_PADDING) -+ plain1 = key.public_decrypt(cipher, OpenSSL::PKey::RSA::NO_PADDING) -+ assert_equal(plain0, plain1) -+ -+ # Need smaller size for pkcs1 mode -+ plain0 = "x" * (bits/8 - 11) -+ cipher1 = key.private_encrypt(plain0, OpenSSL::PKey::RSA::PKCS1_PADDING) -+ plain1 = key.public_decrypt(cipher1, OpenSSL::PKey::RSA::PKCS1_PADDING) -+ assert_equal(plain0, plain1) -+ -+ cipherdef = key.private_encrypt(plain0) # PKCS1_PADDING is default -+ plain1 = key.public_decrypt(cipherdef) -+ assert_equal(plain0, plain1) -+ assert_equal(cipher1, cipherdef) -+ -+ # Failure cases -+ assert_raise(ArgumentError){ key.private_encrypt() } -+ assert_raise(ArgumentError){ key.private_encrypt("hi", 1, nil) } -+ assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt(plain0, 666) } -+ end -+ -+ - def test_verify_empty_rsa - rsa = OpenSSL::PKey::RSA.new - assert_raise(OpenSSL::PKey::PKeyError, "[Bug #12783]") { --- -2.32.0 - - -From 4330b1b9661fcab1172473f4fdd9986602c1e78c Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 18 May 2020 20:24:08 +0900 -Subject: [PATCH 4/6] pkey/rsa: port RSA#{private,public}_{encrypt,decrypt} to - the EVP API - -Implement these methods using the new OpenSSL::PKey::PKey#{encrypt,sign} -family. The definitions are now in lib/openssl/pkey.rb. - -Also, recommend using those generic methods in the documentation. ---- - ext/openssl/lib/openssl/pkey.rb | 106 ++++++++++++++++++++++++ - ext/openssl/ossl_pkey_rsa.c | 141 -------------------------------- - 2 files changed, 106 insertions(+), 141 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 569559e1ce..dd8c7c0b09 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -243,5 +243,111 @@ def new(*args, &blk) # :nodoc: - end - end - end -+ -+ # :call-seq: -+ # rsa.private_encrypt(string) -> String -+ # rsa.private_encrypt(string, padding) -> String -+ # -+ # Encrypt +string+ with the private key. +padding+ defaults to -+ # PKCS1_PADDING. The encrypted string output can be decrypted using -+ # #public_decrypt. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and -+ # PKey::PKey#verify_recover instead. -+ def private_encrypt(string, padding = PKCS1_PADDING) -+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA" -+ private? or raise OpenSSL::PKey::RSAError, "private key needed." -+ begin -+ sign_raw(nil, string, { -+ "rsa_padding_mode" => translate_padding_mode(padding), -+ }) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::RSAError, $!.message -+ end -+ end -+ -+ # :call-seq: -+ # rsa.public_decrypt(string) -> String -+ # rsa.public_decrypt(string, padding) -> String -+ # -+ # Decrypt +string+, which has been encrypted with the private key, with the -+ # public key. +padding+ defaults to PKCS1_PADDING. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and -+ # PKey::PKey#verify_recover instead. -+ def public_decrypt(string, padding = PKCS1_PADDING) -+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA" -+ begin -+ verify_recover(nil, string, { -+ "rsa_padding_mode" => translate_padding_mode(padding), -+ }) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::RSAError, $!.message -+ end -+ end -+ -+ # :call-seq: -+ # rsa.public_encrypt(string) -> String -+ # rsa.public_encrypt(string, padding) -> String -+ # -+ # Encrypt +string+ with the public key. +padding+ defaults to -+ # PKCS1_PADDING. The encrypted string output can be decrypted using -+ # #private_decrypt. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. -+ def public_encrypt(data, padding = PKCS1_PADDING) -+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA" -+ begin -+ encrypt(data, { -+ "rsa_padding_mode" => translate_padding_mode(padding), -+ }) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::RSAError, $!.message -+ end -+ end -+ -+ # :call-seq: -+ # rsa.private_decrypt(string) -> String -+ # rsa.private_decrypt(string, padding) -> String -+ # -+ # Decrypt +string+, which has been encrypted with the public key, with the -+ # private key. +padding+ defaults to PKCS1_PADDING. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. -+ def private_decrypt(data, padding = PKCS1_PADDING) -+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA" -+ private? or raise OpenSSL::PKey::RSAError, "private key needed." -+ begin -+ decrypt(data, { -+ "rsa_padding_mode" => translate_padding_mode(padding), -+ }) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::RSAError, $!.message -+ end -+ end -+ -+ PKCS1_PADDING = 1 -+ SSLV23_PADDING = 2 -+ NO_PADDING = 3 -+ PKCS1_OAEP_PADDING = 4 -+ -+ private def translate_padding_mode(num) -+ case num -+ when PKCS1_PADDING -+ "pkcs1" -+ when SSLV23_PADDING -+ "sslv23" -+ when NO_PADDING -+ "none" -+ when PKCS1_OAEP_PADDING -+ "oaep" -+ else -+ raise OpenSSL::PKey::PKeyError, "unsupported padding mode" -+ end -+ end - end - end -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 1c5476cdcd..8ebd3ec559 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -229,138 +229,6 @@ ossl_rsa_to_der(VALUE self) - return ossl_pkey_export_spki(self, 1); - } - --/* -- * call-seq: -- * rsa.public_encrypt(string) => String -- * rsa.public_encrypt(string, padding) => String -- * -- * Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING. -- * The encrypted string output can be decrypted using #private_decrypt. -- */ --static VALUE --ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self) --{ -- RSA *rsa; -- const BIGNUM *rsa_n; -- int buf_len, pad; -- VALUE str, buffer, padding; -- -- GetRSA(self, rsa); -- RSA_get0_key(rsa, &rsa_n, NULL, NULL); -- if (!rsa_n) -- ossl_raise(eRSAError, "incomplete RSA"); -- rb_scan_args(argc, argv, "11", &buffer, &padding); -- pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); -- StringValue(buffer); -- str = rb_str_new(0, RSA_size(rsa)); -- buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), -- (unsigned char *)RSTRING_PTR(str), rsa, pad); -- if (buf_len < 0) ossl_raise(eRSAError, NULL); -- rb_str_set_len(str, buf_len); -- -- return str; --} -- --/* -- * call-seq: -- * rsa.public_decrypt(string) => String -- * rsa.public_decrypt(string, padding) => String -- * -- * Decrypt _string_, which has been encrypted with the private key, with the -- * public key. _padding_ defaults to PKCS1_PADDING. -- */ --static VALUE --ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self) --{ -- RSA *rsa; -- const BIGNUM *rsa_n; -- int buf_len, pad; -- VALUE str, buffer, padding; -- -- GetRSA(self, rsa); -- RSA_get0_key(rsa, &rsa_n, NULL, NULL); -- if (!rsa_n) -- ossl_raise(eRSAError, "incomplete RSA"); -- rb_scan_args(argc, argv, "11", &buffer, &padding); -- pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); -- StringValue(buffer); -- str = rb_str_new(0, RSA_size(rsa)); -- buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), -- (unsigned char *)RSTRING_PTR(str), rsa, pad); -- if (buf_len < 0) ossl_raise(eRSAError, NULL); -- rb_str_set_len(str, buf_len); -- -- return str; --} -- --/* -- * call-seq: -- * rsa.private_encrypt(string) => String -- * rsa.private_encrypt(string, padding) => String -- * -- * Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING. -- * The encrypted string output can be decrypted using #public_decrypt. -- */ --static VALUE --ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self) --{ -- RSA *rsa; -- const BIGNUM *rsa_n; -- int buf_len, pad; -- VALUE str, buffer, padding; -- -- GetRSA(self, rsa); -- RSA_get0_key(rsa, &rsa_n, NULL, NULL); -- if (!rsa_n) -- ossl_raise(eRSAError, "incomplete RSA"); -- if (!RSA_PRIVATE(self, rsa)) -- ossl_raise(eRSAError, "private key needed."); -- rb_scan_args(argc, argv, "11", &buffer, &padding); -- pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); -- StringValue(buffer); -- str = rb_str_new(0, RSA_size(rsa)); -- buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), -- (unsigned char *)RSTRING_PTR(str), rsa, pad); -- if (buf_len < 0) ossl_raise(eRSAError, NULL); -- rb_str_set_len(str, buf_len); -- -- return str; --} -- --/* -- * call-seq: -- * rsa.private_decrypt(string) => String -- * rsa.private_decrypt(string, padding) => String -- * -- * Decrypt _string_, which has been encrypted with the public key, with the -- * private key. _padding_ defaults to PKCS1_PADDING. -- */ --static VALUE --ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) --{ -- RSA *rsa; -- const BIGNUM *rsa_n; -- int buf_len, pad; -- VALUE str, buffer, padding; -- -- GetRSA(self, rsa); -- RSA_get0_key(rsa, &rsa_n, NULL, NULL); -- if (!rsa_n) -- ossl_raise(eRSAError, "incomplete RSA"); -- if (!RSA_PRIVATE(self, rsa)) -- ossl_raise(eRSAError, "private key needed."); -- rb_scan_args(argc, argv, "11", &buffer, &padding); -- pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); -- StringValue(buffer); -- str = rb_str_new(0, RSA_size(rsa)); -- buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), -- (unsigned char *)RSTRING_PTR(str), rsa, pad); -- if (buf_len < 0) ossl_raise(eRSAError, NULL); -- rb_str_set_len(str, buf_len); -- -- return str; --} -- - /* - * call-seq: - * rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String -@@ -657,10 +525,6 @@ Init_ossl_rsa(void) - rb_define_alias(cRSA, "to_pem", "export"); - rb_define_alias(cRSA, "to_s", "export"); - rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); -- rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); -- rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); -- rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); -- rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1); - rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1); - rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1); - -@@ -678,11 +542,6 @@ Init_ossl_rsa(void) - - rb_define_method(cRSA, "params", ossl_rsa_get_params, 0); - -- DefRSAConst(PKCS1_PADDING); -- DefRSAConst(SSLV23_PADDING); -- DefRSAConst(NO_PADDING); -- DefRSAConst(PKCS1_OAEP_PADDING); -- - /* - * TODO: Test it - rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); --- -2.32.0 - - -From d45a31cf70f5a55d7f6cf5082efc4dbb68d1169d Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 10 Jul 2020 13:43:20 +0900 -Subject: [PATCH 5/6] pkey/ec: refactor EC#dsa_{sign,verify}_asn1 with - PKey#{sign,verify}_raw - -With the newly added OpenSSL::PKey::PKey#{sign,verify}_raw, -OpenSSL::PKey::EC's low level signing operation methods can be -implemented in Ruby. The definitions are now in lib/openssl/pkey.rb. ---- - ext/openssl/lib/openssl/pkey.rb | 22 +++++++++++++ - ext/openssl/ossl_pkey_ec.c | 55 --------------------------------- - 2 files changed, 22 insertions(+), 55 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index dd8c7c0b09..e587109694 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -164,6 +164,28 @@ def new(*args, &blk) # :nodoc: - class EC - include OpenSSL::Marshal - -+ # :call-seq: -+ # key.dsa_sign_asn1(data) -> String -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. -+ def dsa_sign_asn1(data) -+ sign_raw(nil, data) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::ECError, $!.message -+ end -+ -+ # :call-seq: -+ # key.dsa_verify_asn1(data, sig) -> true | false -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. -+ def dsa_verify_asn1(data, sig) -+ verify_raw(nil, sig, data) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::ECError, $!.message -+ end -+ - # :call-seq: - # ec.dh_compute_key(pubkey) -> string - # -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index 829529d4b9..f52e67079d 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -476,57 +476,6 @@ static VALUE ossl_ec_key_check_key(VALUE self) - return Qtrue; - } - --/* -- * call-seq: -- * key.dsa_sign_asn1(data) => String -- * -- * See the OpenSSL documentation for ECDSA_sign() -- */ --static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data) --{ -- EC_KEY *ec; -- unsigned int buf_len; -- VALUE str; -- -- GetEC(self, ec); -- StringValue(data); -- -- if (EC_KEY_get0_private_key(ec) == NULL) -- ossl_raise(eECError, "Private EC key needed!"); -- -- str = rb_str_new(0, ECDSA_size(ec)); -- if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1) -- ossl_raise(eECError, "ECDSA_sign"); -- rb_str_set_len(str, buf_len); -- -- return str; --} -- --/* -- * call-seq: -- * key.dsa_verify_asn1(data, sig) => true or false -- * -- * See the OpenSSL documentation for ECDSA_verify() -- */ --static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) --{ -- EC_KEY *ec; -- -- GetEC(self, ec); -- StringValue(data); -- StringValue(sig); -- -- switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data), -- (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) { -- case 1: -- return Qtrue; -- case 0: -- return Qfalse; -- default: -- ossl_raise(eECError, "ECDSA_verify"); -- } --} -- - /* - * OpenSSL::PKey::EC::Group - */ -@@ -1615,10 +1564,6 @@ void Init_ossl_ec(void) - rb_define_alias(cEC, "generate_key", "generate_key!"); - rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0); - -- rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1); -- rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2); --/* do_sign/do_verify */ -- - rb_define_method(cEC, "export", ossl_ec_key_export, -1); - rb_define_alias(cEC, "to_pem", "export"); - rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); --- -2.32.0 - - -From 2494043e302c920e90e06cce443c5cd428e183f7 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 10 Jul 2020 13:51:18 +0900 -Subject: [PATCH 6/6] pkey/dsa: refactor DSA#sys{sign,verify} with - PKey#{sign,verify}_raw - -With the newly added OpenSSL::PKey::PKey#{sign,verify}_raw, -OpenSSL::PKey::DSA's low level signing operation methods can be -implemented in Ruby. The definitions are now in lib/openssl/pkey.rb. ---- - ext/openssl/lib/openssl/pkey.rb | 54 ++++++++++++++++++++ - ext/openssl/ossl_pkey_dsa.c | 88 --------------------------------- - 2 files changed, 54 insertions(+), 88 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index e587109694..f6bf5892b0 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -158,6 +158,60 @@ def new(*args, &blk) # :nodoc: - end - end - end -+ -+ # :call-seq: -+ # dsa.syssign(string) -> string -+ # -+ # Computes and returns the \DSA signature of +string+, where +string+ is -+ # expected to be an already-computed message digest of the original input -+ # data. The signature is issued using the private key of this DSA instance. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. -+ # -+ # +string+:: -+ # A message digest of the original input data to be signed. -+ # -+ # Example: -+ # dsa = OpenSSL::PKey::DSA.new(2048) -+ # doc = "Sign me" -+ # digest = OpenSSL::Digest.digest('SHA1', doc) -+ # -+ # # With legacy #syssign and #sysverify: -+ # sig = dsa.syssign(digest) -+ # p dsa.sysverify(digest, sig) #=> true -+ # -+ # # With #sign_raw and #verify_raw: -+ # sig = dsa.sign_raw(nil, digest) -+ # p dsa.verify_raw(nil, sig, digest) #=> true -+ def syssign(string) -+ q or raise OpenSSL::PKey::DSAError, "incomplete DSA" -+ private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!" -+ begin -+ sign_raw(nil, string) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::DSAError, $!.message -+ end -+ end -+ -+ # :call-seq: -+ # dsa.sysverify(digest, sig) -> true | false -+ # -+ # Verifies whether the signature is valid given the message digest input. -+ # It does so by validating +sig+ using the public key of this DSA instance. -+ # -+ # Deprecated in version 3.0. -+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. -+ # -+ # +digest+:: -+ # A message digest of the original input data to be signed. -+ # +sig+:: -+ # A \DSA signature value. -+ def sysverify(digest, sig) -+ verify_raw(nil, sig, digest) -+ rescue OpenSSL::PKey::PKeyError -+ raise OpenSSL::PKey::DSAError, $!.message -+ end - end - - if defined?(EC) -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index ab9ac781e8..7af00eebec 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -264,92 +264,6 @@ ossl_dsa_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * dsa.syssign(string) -> aString -- * -- * Computes and returns the DSA signature of _string_, where _string_ is -- * expected to be an already-computed message digest of the original input -- * data. The signature is issued using the private key of this DSA instance. -- * -- * === Parameters -- * * _string_ is a message digest of the original input data to be signed. -- * -- * === Example -- * dsa = OpenSSL::PKey::DSA.new(2048) -- * doc = "Sign me" -- * digest = OpenSSL::Digest.digest('SHA1', doc) -- * sig = dsa.syssign(digest) -- * -- * -- */ --static VALUE --ossl_dsa_sign(VALUE self, VALUE data) --{ -- DSA *dsa; -- const BIGNUM *dsa_q; -- unsigned int buf_len; -- VALUE str; -- -- GetDSA(self, dsa); -- DSA_get0_pqg(dsa, NULL, &dsa_q, NULL); -- if (!dsa_q) -- ossl_raise(eDSAError, "incomplete DSA"); -- if (!DSA_PRIVATE(self, dsa)) -- ossl_raise(eDSAError, "Private DSA key needed!"); -- StringValue(data); -- str = rb_str_new(0, DSA_size(dsa)); -- if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data), -- (unsigned char *)RSTRING_PTR(str), -- &buf_len, dsa)) { /* type is ignored (0) */ -- ossl_raise(eDSAError, NULL); -- } -- rb_str_set_len(str, buf_len); -- -- return str; --} -- --/* -- * call-seq: -- * dsa.sysverify(digest, sig) -> true | false -- * -- * Verifies whether the signature is valid given the message digest input. It -- * does so by validating _sig_ using the public key of this DSA instance. -- * -- * === Parameters -- * * _digest_ is a message digest of the original input data to be signed -- * * _sig_ is a DSA signature value -- * -- * === Example -- * dsa = OpenSSL::PKey::DSA.new(2048) -- * doc = "Sign me" -- * digest = OpenSSL::Digest.digest('SHA1', doc) -- * sig = dsa.syssign(digest) -- * puts dsa.sysverify(digest, sig) # => true -- * -- */ --static VALUE --ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig) --{ -- DSA *dsa; -- int ret; -- -- GetDSA(self, dsa); -- StringValue(digest); -- StringValue(sig); -- /* type is ignored (0) */ -- ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest), -- (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa); -- if (ret < 0) { -- ossl_raise(eDSAError, NULL); -- } -- else if (ret == 1) { -- return Qtrue; -- } -- -- return Qfalse; --} -- - /* - * Document-method: OpenSSL::PKey::DSA#set_pqg - * call-seq: -@@ -404,8 +318,6 @@ Init_ossl_dsa(void) - rb_define_alias(cDSA, "to_pem", "export"); - rb_define_alias(cDSA, "to_s", "export"); - rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); -- rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); -- rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); - - DEF_OSSL_PKEY_BN(cDSA, dsa, p); - DEF_OSSL_PKEY_BN(cDSA, dsa, q); --- -2.32.0 - diff --git a/ruby-3.1.0-Migrate-from-the-low-level-HMAC-API-to-the-EVP-API.patch b/ruby-3.1.0-Migrate-from-the-low-level-HMAC-API-to-the-EVP-API.patch deleted file mode 100644 index d25cae9..0000000 --- a/ruby-3.1.0-Migrate-from-the-low-level-HMAC-API-to-the-EVP-API.patch +++ /dev/null @@ -1,523 +0,0 @@ -From 8253d7c9cea16c2aa009b59db4f5d93afb74c6eb Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 30 Jun 2020 14:27:13 +0900 -Subject: [PATCH 1/2] hmac: add a test case for OpenSSL::HMAC singleton methods - ---- - test/openssl/test_hmac.rb | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb -index 9cb3c5a86..7202a5902 100644 ---- a/test/openssl/test_hmac.rb -+++ b/test/openssl/test_hmac.rb -@@ -49,6 +49,15 @@ def test_eq - refute_equal h1, h2.digest - refute_equal h1, h3 - end -+ -+ def test_singleton_methods -+ # RFC 2202 2. Test Cases for HMAC-MD5 -+ key = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") -+ digest = OpenSSL::HMAC.digest("MD5", key, "Hi There") -+ assert_equal ["9294727a3638bb1c13f48ef8158bfc9d"].pack("H*"), digest -+ hexdigest = OpenSSL::HMAC.hexdigest("MD5", key, "Hi There") -+ assert_equal "9294727a3638bb1c13f48ef8158bfc9d", hexdigest -+ end - end - - end - -From 0317e2fc028be40a7d64d0e4337d3e21539613ce Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 18 May 2020 16:15:07 +0900 -Subject: [PATCH 2/2] hmac: migrate from the low-level HMAC API to the EVP API - -Use the EVP API instead of the low-level HMAC API. Use of the HMAC API -has been discouraged and is being marked as deprecated starting from -OpenSSL 3.0.0. - -The two singleton methods OpenSSL::HMAC, HMAC.digest and HMAC.hexdigest -are now in lib/openssl/hmac.rb. ---- - ext/openssl/extconf.rb | 3 +- - ext/openssl/lib/openssl/hmac.rb | 40 +++++++ - ext/openssl/openssl_missing.c | 26 ----- - ext/openssl/openssl_missing.h | 10 +- - ext/openssl/ossl.h | 1 - - ext/openssl/ossl_hmac.c | 179 ++++++++------------------------ - 6 files changed, 89 insertions(+), 170 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 693e55cd9..063498a76 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -141,8 +141,7 @@ def find_openssl_library - have_func("BN_GENCB_get_arg") - have_func("EVP_MD_CTX_new") - have_func("EVP_MD_CTX_free") --have_func("HMAC_CTX_new") --have_func("HMAC_CTX_free") -+have_func("EVP_MD_CTX_pkey_ctx") - have_func("X509_STORE_get_ex_data") - have_func("X509_STORE_set_ex_data") - have_func("X509_STORE_get_ex_new_index") -diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb -index 3d4427611d..9bc8bc8df3 100644 ---- a/ext/openssl/lib/openssl/hmac.rb -+++ b/ext/openssl/lib/openssl/hmac.rb -@@ -9,5 +9,45 @@ def ==(other) - - OpenSSL.fixed_length_secure_compare(self.digest, other.digest) - end -+ -+ class << self -+ # :call-seq: -+ # HMAC.digest(digest, key, data) -> aString -+ # -+ # Returns the authentication code as a binary string. The _digest_ parameter -+ # specifies the digest algorithm to use. This may be a String representing -+ # the algorithm name or an instance of OpenSSL::Digest. -+ # -+ # === Example -+ # key = 'key' -+ # data = 'The quick brown fox jumps over the lazy dog' -+ # -+ # hmac = OpenSSL::HMAC.digest('SHA1', key, data) -+ # #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" -+ def digest(digest, key, data) -+ hmac = new(key, digest) -+ hmac << data -+ hmac.digest -+ end -+ -+ # :call-seq: -+ # HMAC.hexdigest(digest, key, data) -> aString -+ # -+ # Returns the authentication code as a hex-encoded string. The _digest_ -+ # parameter specifies the digest algorithm to use. This may be a String -+ # representing the algorithm name or an instance of OpenSSL::Digest. -+ # -+ # === Example -+ # key = 'key' -+ # data = 'The quick brown fox jumps over the lazy dog' -+ # -+ # hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) -+ # #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" -+ def hexdigest(digest, key, data) -+ hmac = new(key, digest) -+ hmac << data -+ hmac.hexdigest -+ end -+ end - end - end -diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c -index b36ef0288..010c158dc 100644 ---- a/ext/openssl/openssl_missing.c -+++ b/ext/openssl/openssl_missing.c -@@ -13,9 +13,6 @@ - #if !defined(OPENSSL_NO_ENGINE) - # include - #endif --#if !defined(OPENSSL_NO_HMAC) --# include --#endif - #include - - #include "openssl_missing.h" -@@ -58,29 +55,6 @@ ossl_EC_curve_nist2nid(const char *name) - #endif - - /*** added in 1.1.0 ***/ --#if !defined(HAVE_HMAC_CTX_NEW) --HMAC_CTX * --ossl_HMAC_CTX_new(void) --{ -- HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); -- if (!ctx) -- return NULL; -- HMAC_CTX_init(ctx); -- return ctx; --} --#endif -- --#if !defined(HAVE_HMAC_CTX_FREE) --void --ossl_HMAC_CTX_free(HMAC_CTX *ctx) --{ -- if (ctx) { -- HMAC_CTX_cleanup(ctx); -- OPENSSL_free(ctx); -- } --} --#endif -- - #if !defined(HAVE_X509_CRL_GET0_SIGNATURE) - void - ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, -diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h -index 7d218f86f..06d2a9082 100644 ---- a/ext/openssl/openssl_missing.h -+++ b/ext/openssl/openssl_missing.h -@@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *); - # define EVP_MD_CTX_free EVP_MD_CTX_destroy - #endif - --#if !defined(HAVE_HMAC_CTX_NEW) --HMAC_CTX *ossl_HMAC_CTX_new(void); --# define HMAC_CTX_new ossl_HMAC_CTX_new --#endif -- --#if !defined(HAVE_HMAC_CTX_FREE) --void ossl_HMAC_CTX_free(HMAC_CTX *); --# define HMAC_CTX_free ossl_HMAC_CTX_free -+#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX) -+# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx - #endif - - #if !defined(HAVE_X509_STORE_GET_EX_DATA) -diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h -index c20f506bd..577eb6d6b 100644 ---- a/ext/openssl/ossl.h -+++ b/ext/openssl/ossl.h -@@ -24,7 +24,6 @@ - #include - #include - #include --#include - #include - #include - #ifndef OPENSSL_NO_TS -diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c -index 70e9fb819..a21db6c48 100644 ---- a/ext/openssl/ossl_hmac.c -+++ b/ext/openssl/ossl_hmac.c -@@ -7,14 +7,12 @@ - * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ --#if !defined(OPENSSL_NO_HMAC) -- - #include "ossl.h" - - #define NewHMAC(klass) \ - TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0) - #define GetHMAC(obj, ctx) do { \ -- TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ -+ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ - } \ -@@ -36,7 +34,7 @@ VALUE eHMACError; - static void - ossl_hmac_free(void *ctx) - { -- HMAC_CTX_free(ctx); -+ EVP_MD_CTX_free(ctx); - } - - static const rb_data_type_t ossl_hmac_type = { -@@ -51,12 +49,12 @@ static VALUE - ossl_hmac_alloc(VALUE klass) - { - VALUE obj; -- HMAC_CTX *ctx; -+ EVP_MD_CTX *ctx; - - obj = NewHMAC(klass); -- ctx = HMAC_CTX_new(); -+ ctx = EVP_MD_CTX_new(); - if (!ctx) -- ossl_raise(eHMACError, NULL); -+ ossl_raise(eHMACError, "EVP_MD_CTX"); - RTYPEDDATA_DATA(obj) = ctx; - - return obj; -@@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass) - * === Example - * - * key = 'key' -- * digest = OpenSSL::Digest.new('sha1') -- * instance = OpenSSL::HMAC.new(key, digest) -+ * instance = OpenSSL::HMAC.new(key, 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance.class - * #=> OpenSSL::HMAC -@@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass) - * - * Two instances can be securely compared with #== in constant time: - * -- * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) -+ * other_instance = OpenSSL::HMAC.new('key', 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance == other_instance - * #=> true -@@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass) - static VALUE - ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) - { -- HMAC_CTX *ctx; -+ EVP_MD_CTX *ctx; -+ EVP_PKEY *pkey; - -- StringValue(key); - GetHMAC(self, ctx); -- HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), -- ossl_evp_get_digestbyname(digest), NULL); -+ StringValue(key); -+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, -+ (unsigned char *)RSTRING_PTR(key), -+ RSTRING_LENINT(key)); -+ if (!pkey) -+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key"); -+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest), -+ NULL, pkey) != 1) { -+ EVP_PKEY_free(pkey); -+ ossl_raise(eHMACError, "EVP_DigestSignInit"); -+ } -+ /* Decrement reference counter; EVP_MD_CTX still keeps it */ -+ EVP_PKEY_free(pkey); - - return self; - } -@@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) - static VALUE - ossl_hmac_copy(VALUE self, VALUE other) - { -- HMAC_CTX *ctx1, *ctx2; -+ EVP_MD_CTX *ctx1, *ctx2; - - rb_check_frozen(self); - if (self == other) return self; - - GetHMAC(self, ctx1); - GetHMAC(other, ctx2); -- -- if (!HMAC_CTX_copy(ctx1, ctx2)) -- ossl_raise(eHMACError, "HMAC_CTX_copy"); -+ if (EVP_MD_CTX_copy(ctx1, ctx2) != 1) -+ ossl_raise(eHMACError, "EVP_MD_CTX_copy"); - return self; - } - -@@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other) - static VALUE - ossl_hmac_update(VALUE self, VALUE data) - { -- HMAC_CTX *ctx; -+ EVP_MD_CTX *ctx; - - StringValue(data); - GetHMAC(self, ctx); -- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)); -+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) -+ ossl_raise(eHMACError, "EVP_DigestSignUpdate"); - - return self; - } - --static void --hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) --{ -- HMAC_CTX *final; -- -- final = HMAC_CTX_new(); -- if (!final) -- ossl_raise(eHMACError, "HMAC_CTX_new"); -- -- if (!HMAC_CTX_copy(final, ctx)) { -- HMAC_CTX_free(final); -- ossl_raise(eHMACError, "HMAC_CTX_copy"); -- } -- -- HMAC_Final(final, buf, buf_len); -- HMAC_CTX_free(final); --} -- - /* - * call-seq: - * hmac.digest -> string -@@ -176,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) - * Returns the authentication code an instance represents as a binary string. - * - * === Example -- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) -+ * instance = OpenSSL::HMAC.new('key', 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance.digest - * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" -@@ -184,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) - static VALUE - ossl_hmac_digest(VALUE self) - { -- HMAC_CTX *ctx; -- unsigned int buf_len; -+ EVP_MD_CTX *ctx; -+ size_t buf_len; - VALUE ret; - - GetHMAC(self, ctx); - ret = rb_str_new(NULL, EVP_MAX_MD_SIZE); -- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len); -- assert(buf_len <= EVP_MAX_MD_SIZE); -- rb_str_set_len(ret, buf_len); -+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret), -+ &buf_len) != 1) -+ ossl_raise(eHMACError, "EVP_DigestSignFinal"); -+ rb_str_set_len(ret, (long)buf_len); - - return ret; - } -@@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self) - static VALUE - ossl_hmac_hexdigest(VALUE self) - { -- HMAC_CTX *ctx; -+ EVP_MD_CTX *ctx; - unsigned char buf[EVP_MAX_MD_SIZE]; -- unsigned int buf_len; -+ size_t buf_len; - VALUE ret; - - GetHMAC(self, ctx); -- hmac_final(ctx, buf, &buf_len); -+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1) -+ ossl_raise(eHMACError, "EVP_DigestSignFinal"); - ret = rb_str_new(NULL, buf_len * 2); - ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); - -@@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self) - * === Example - * - * data = "The quick brown fox jumps over the lazy dog" -- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) -+ * instance = OpenSSL::HMAC.new('key', 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * - * instance.update(data) -@@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self) - static VALUE - ossl_hmac_reset(VALUE self) - { -- HMAC_CTX *ctx; -+ EVP_MD_CTX *ctx; -+ EVP_PKEY *pkey; - - GetHMAC(self, ctx); -- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL); -+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); -+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1) -+ ossl_raise(eHMACError, "EVP_DigestSignInit"); - - return self; - } - --/* -- * call-seq: -- * HMAC.digest(digest, key, data) -> aString -- * -- * Returns the authentication code as a binary string. The _digest_ parameter -- * specifies the digest algorithm to use. This may be a String representing -- * the algorithm name or an instance of OpenSSL::Digest. -- * -- * === Example -- * -- * key = 'key' -- * data = 'The quick brown fox jumps over the lazy dog' -- * -- * hmac = OpenSSL::HMAC.digest('sha1', key, data) -- * #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" -- * -- */ --static VALUE --ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data) --{ -- unsigned char *buf; -- unsigned int buf_len; -- -- StringValue(key); -- StringValue(data); -- buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), -- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), -- RSTRING_LEN(data), NULL, &buf_len); -- -- return rb_str_new((const char *)buf, buf_len); --} -- --/* -- * call-seq: -- * HMAC.hexdigest(digest, key, data) -> aString -- * -- * Returns the authentication code as a hex-encoded string. The _digest_ -- * parameter specifies the digest algorithm to use. This may be a String -- * representing the algorithm name or an instance of OpenSSL::Digest. -- * -- * === Example -- * -- * key = 'key' -- * data = 'The quick brown fox jumps over the lazy dog' -- * -- * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data) -- * #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" -- * -- */ --static VALUE --ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data) --{ -- unsigned char buf[EVP_MAX_MD_SIZE]; -- unsigned int buf_len; -- VALUE ret; -- -- StringValue(key); -- StringValue(data); -- -- if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), -- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), -- RSTRING_LEN(data), buf, &buf_len)) -- ossl_raise(eHMACError, "HMAC"); -- -- ret = rb_str_new(NULL, buf_len * 2); -- ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); -- -- return ret; --} -- - /* - * INIT - */ -@@ -353,8 +278,7 @@ Init_ossl_hmac(void) - * data1 = File.read("file1") - * data2 = File.read("file2") - * key = "key" -- * digest = OpenSSL::Digest.new('SHA256') -- * hmac = OpenSSL::HMAC.new(key, digest) -+ * hmac = OpenSSL::HMAC.new(key, 'SHA256') - * hmac << data1 - * hmac << data2 - * mac = hmac.digest -@@ -364,8 +288,6 @@ Init_ossl_hmac(void) - cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject); - - rb_define_alloc_func(cHMAC, ossl_hmac_alloc); -- rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3); -- rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3); - - rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2); - rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1); -@@ -378,12 +300,3 @@ Init_ossl_hmac(void) - rb_define_alias(cHMAC, "inspect", "hexdigest"); - rb_define_alias(cHMAC, "to_s", "hexdigest"); - } -- --#else /* NO_HMAC */ --# warning >>> OpenSSL is compiled without HMAC support <<< --void --Init_ossl_hmac(void) --{ -- rb_warning("HMAC is not available: OpenSSL is compiled without HMAC."); --} --#endif /* NO_HMAC */ --- -2.34.1 - diff --git a/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support-part-2.patch b/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support-part-2.patch deleted file mode 100644 index b906c19..0000000 --- a/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support-part-2.patch +++ /dev/null @@ -1,458 +0,0 @@ -From 91d04f991f8b9910efea7bbe5aecb0fea2bbd5fa Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 24 Oct 2021 17:50:18 +0900 -Subject: [PATCH 1/8] cipher: update test_ciphers - -Do not attempt to actually use all algorithms. Not all algorithms listed -in OpenSSL::Cipher.ciphers are always available. ---- - test/openssl/test_cipher.rb | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb -index 6d18c0c8..b5fdf0b3 100644 ---- a/test/openssl/test_cipher.rb -+++ b/test/openssl/test_cipher.rb -@@ -135,14 +135,11 @@ def test_ctr_if_exists - end - - def test_ciphers -- OpenSSL::Cipher.ciphers.each{|name| -- next if /netbsd/ =~ RUBY_PLATFORM && /idea|rc5/i =~ name -- begin -- assert_kind_of(OpenSSL::Cipher, OpenSSL::Cipher.new(name)) -- rescue OpenSSL::Cipher::CipherError => e -- raise unless /wrap/ =~ name and /wrap mode not allowed/ =~ e.message -- end -- } -+ ciphers = OpenSSL::Cipher.ciphers -+ assert_kind_of Array, ciphers -+ assert_include ciphers, "aes-128-cbc" -+ assert_include ciphers, "aes128" # alias of aes-128-cbc -+ assert_include ciphers, "aes-128-gcm" - end - - def test_AES - -From 6a60c7b2e7b6afe8b8c98d864ef2740094d86e1d Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 11 Dec 2021 16:27:42 +0900 -Subject: [PATCH 2/8] hmac: fix wrong usage of EVP_DigestSignFinal() - -According to the manpage, the "siglen" parameter must be initialized -beforehand. ---- - ext/openssl/ossl_hmac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c -index f89ff2f9..bfe3a74b 100644 ---- a/ext/openssl/ossl_hmac.c -+++ b/ext/openssl/ossl_hmac.c -@@ -175,7 +175,7 @@ static VALUE - ossl_hmac_digest(VALUE self) - { - EVP_MD_CTX *ctx; -- size_t buf_len; -+ size_t buf_len = EVP_MAX_MD_SIZE; - VALUE ret; - - GetHMAC(self, ctx); -@@ -200,7 +200,7 @@ ossl_hmac_hexdigest(VALUE self) - { - EVP_MD_CTX *ctx; - unsigned char buf[EVP_MAX_MD_SIZE]; -- size_t buf_len; -+ size_t buf_len = EVP_MAX_MD_SIZE; - VALUE ret; - - GetHMAC(self, ctx); - -From 46995816392a79d037df5550b2fb226652c06f42 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 11 Dec 2021 16:30:30 +0900 -Subject: [PATCH 3/8] hmac: skip test_dup on OpenSSL 3.0 for now - -EVP_MD_CTX_copy() doesn't seem to work as intended on HMAC EVP_MD_CTX -on OpenSSL 3.0.0 and causes a double free. I haven't found the root -problem yet, but let's skip the test case for now. ---- - test/openssl/test_hmac.rb | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb -index 2f53a813..47cb3718 100644 ---- a/test/openssl/test_hmac.rb -+++ b/test/openssl/test_hmac.rb -@@ -19,6 +19,7 @@ def test_hmac - end - - def test_dup -+ pend "HMAC#initialize_copy is currently broken on OpenSSL 3.0.0" if openssl?(3, 0, 0) - h1 = OpenSSL::HMAC.new("KEY", "MD5") - h1.update("DATA") - h = h1.dup - -From 69a27d8de4bd291cb4eb21a4d715b197e7da5a06 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 15 Apr 2021 00:51:58 +0900 -Subject: [PATCH 4/8] engine: disable OpenSSL::Engine on OpenSSL 3.0 - -The entire ENGINE API is deprecated in OpenSSL 3.0 in favor of the new -"Provider" concept. - -OpenSSL::Engine will not be defined when compiled with OpenSSL 3.0. -We would need a way to interact with providers from Ruby programs, but -since the concept is completely different from the ENGINE API, it will -not be through the current OpenSSL::Engine interface. ---- - ext/openssl/openssl_missing.c | 3 --- - ext/openssl/ossl.h | 8 +++++--- - ext/openssl/ossl_engine.c | 3 ++- - ext/openssl/ossl_pkey.c | 4 ++++ - 4 files changed, 11 insertions(+), 7 deletions(-) - -diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c -index 8b93cba6..4415703d 100644 ---- a/ext/openssl/openssl_missing.c -+++ b/ext/openssl/openssl_missing.c -@@ -10,9 +10,6 @@ - #include RUBY_EXTCONF_H - - #include /* memcpy() */ --#if !defined(OPENSSL_NO_ENGINE) --# include --#endif - #include - - #include "openssl_missing.h" -diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h -index 3a0ab1e5..4b512689 100644 ---- a/ext/openssl/ossl.h -+++ b/ext/openssl/ossl.h -@@ -18,6 +18,7 @@ - #include - #include - #include -+ - #include - #include - #include -@@ -30,9 +31,6 @@ - #include - #endif - #include --#if !defined(OPENSSL_NO_ENGINE) --# include --#endif - #if !defined(OPENSSL_NO_OCSP) - # include - #endif -@@ -54,6 +52,10 @@ - (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) - #endif - -+#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) -+# define OSSL_USE_ENGINE -+#endif -+ - /* - * Common Module - */ -diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c -index 661a1368..1abde7f7 100644 ---- a/ext/openssl/ossl_engine.c -+++ b/ext/openssl/ossl_engine.c -@@ -9,7 +9,8 @@ - */ - #include "ossl.h" - --#if !defined(OPENSSL_NO_ENGINE) -+#ifdef OSSL_USE_ENGINE -+# include - - #define NewEngine(klass) \ - TypedData_Wrap_Struct((klass), &ossl_engine_type, 0) -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 7030be3c..94760d32 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -9,6 +9,10 @@ - */ - #include "ossl.h" - -+#ifdef OSSL_USE_ENGINE -+# include -+#endif -+ - /* - * Classes - */ - -From b1ee2f23b28c2d0b14fd9b4b9fef13e870370746 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 17 Nov 2021 11:39:06 +0900 -Subject: [PATCH 5/8] ssl: add constants for new SSL_OP_* flags - -Add all SSL_OP_* constants defined in OpenSSL 3.0.0 which are not -specific to DTLS. ---- - ext/openssl/ossl_ssl.c | 35 +++++++++++++++++++++++++++++------ - 1 file changed, 29 insertions(+), 6 deletions(-) - -diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c -index 3b425ca7..9a0682a7 100644 ---- a/ext/openssl/ossl_ssl.c -+++ b/ext/openssl/ossl_ssl.c -@@ -2941,13 +2941,28 @@ Init_ossl_ssl(void) - rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE)); - - rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL)); -+#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */ -+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT)); -+#endif - rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT)); -+#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */ -+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS)); -+#endif - #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */ - rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); - #endif - #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */ - rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)); - #endif -+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */ -+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF)); -+#endif -+#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */ -+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION)); -+#endif -+#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */ -+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES)); -+#endif - #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */ - rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX)); - #endif -@@ -2959,13 +2974,15 @@ Init_ossl_ssl(void) - #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */ - rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC)); - #endif -- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); -- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); --#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ -- rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); -+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */ -+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)); -+#endif -+#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */ -+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA)); -+#endif -+#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */ -+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY)); - #endif -- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); -- - rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3)); - rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1)); - rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1)); -@@ -2973,6 +2990,12 @@ Init_ossl_ssl(void) - #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */ - rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3)); - #endif -+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); -+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); -+#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ -+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); -+#endif -+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); - - /* SSL_OP_* flags for DTLS */ - #if 0 - -From e168df0f3570709bfb38e9a39838bd0a7e78164c Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 12 Dec 2021 00:47:35 +0900 -Subject: [PATCH 6/8] ssl: update test_options_disable_versions - -Use the combination of TLS 1.2 and TLS 1.3 instead of TLS 1.1 and TLS -1.2 so that will the test case will be run on latest platforms. ---- - test/openssl/test_ssl.rb | 75 +++++++++++++++++++++------------------- - 1 file changed, 40 insertions(+), 35 deletions(-) - -diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb -index 22691292..2abade06 100644 ---- a/test/openssl/test_ssl.rb -+++ b/test/openssl/test_ssl.rb -@@ -1180,46 +1180,51 @@ def test_minmax_version - end - - def test_options_disable_versions -- # Note: Use of these OP_* flags has been deprecated since OpenSSL 1.1.0. -+ # It's recommended to use SSLContext#{min,max}_version= instead in real -+ # applications. The purpose of this test case is to check that SSL options -+ # are properly propagated to OpenSSL library. - supported = check_supported_protocol_versions -+ if !defined?(OpenSSL::SSL::TLS1_3_VERSION) || -+ !supported.include?(OpenSSL::SSL::TLS1_2_VERSION) || -+ !supported.include?(OpenSSL::SSL::TLS1_3_VERSION) || -+ !defined?(OpenSSL::SSL::OP_NO_TLSv1_3) # LibreSSL < 3.4 -+ pend "this test case requires both TLS 1.2 and TLS 1.3 to be supported " \ -+ "and enabled by default" -+ end - -- if supported.include?(OpenSSL::SSL::TLS1_1_VERSION) && -- supported.include?(OpenSSL::SSL::TLS1_2_VERSION) -- # Server disables ~ TLS 1.1 -- ctx_proc = proc { |ctx| -- ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | -- OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 -- } -- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| -- # Client only supports TLS 1.1 -- ctx1 = OpenSSL::SSL::SSLContext.new -- ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_1_VERSION -- assert_handshake_error { server_connect(port, ctx1) { } } -+ # Server disables TLS 1.2 and earlier -+ ctx_proc = proc { |ctx| -+ ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | -+ OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 | -+ OpenSSL::SSL::OP_NO_TLSv1_2 -+ } -+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| -+ # Client only supports TLS 1.2 -+ ctx1 = OpenSSL::SSL::SSLContext.new -+ ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION -+ assert_handshake_error { server_connect(port, ctx1) { } } - -- # Client only supports TLS 1.2 -- ctx2 = OpenSSL::SSL::SSLContext.new -- ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_2_VERSION -- assert_nothing_raised { server_connect(port, ctx2) { } } -- } -+ # Client only supports TLS 1.3 -+ ctx2 = OpenSSL::SSL::SSLContext.new -+ ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_3_VERSION -+ assert_nothing_raised { server_connect(port, ctx2) { } } -+ } - -- # Server only supports TLS 1.1 -- ctx_proc = proc { |ctx| -- ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION -- } -- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| -- # Client disables TLS 1.1 -- ctx1 = OpenSSL::SSL::SSLContext.new -- ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_1 -- assert_handshake_error { server_connect(port, ctx1) { } } -+ # Server only supports TLS 1.2 -+ ctx_proc = proc { |ctx| -+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION -+ } -+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| -+ # Client doesn't support TLS 1.2 -+ ctx1 = OpenSSL::SSL::SSLContext.new -+ ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_2 -+ assert_handshake_error { server_connect(port, ctx1) { } } - -- # Client disables TLS 1.2 -- ctx2 = OpenSSL::SSL::SSLContext.new -- ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_2 -- assert_nothing_raised { server_connect(port, ctx2) { } } -- } -- else -- pend "TLS 1.1 and TLS 1.2 must be supported; skipping" -- end -+ # Client supports TLS 1.2 by default -+ ctx2 = OpenSSL::SSL::SSLContext.new -+ ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_3 -+ assert_nothing_raised { server_connect(port, ctx2) { } } -+ } - end - - def test_ssl_methods_constant - -From ccdb6f7bfa5f988a07beecedbf2b6205b6ab8492 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 20 Mar 2021 23:16:41 +0900 -Subject: [PATCH 7/8] pkey: assume a pkey always has public key components on - OpenSSL 3.0 - -OpenSSL 3.0's EVP_PKEY_get0() returns NULL for provider-backed pkeys. -This causes segfault because it was supposed to never return NULL -before. - -We can't check the existence of public key components in this way on -OpenSSL 3.0. Let's just skip it for now. ---- - ext/openssl/ossl_pkey.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 94760d32..09d45d85 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -428,9 +428,19 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self) - return pkey_generate(argc, argv, self, 0); - } - -+/* -+ * TODO: There is no convenient way to check the presence of public key -+ * components on OpenSSL 3.0. But since keys are immutable on 3.0, pkeys without -+ * these should only be created by OpenSSL::PKey.generate_parameters or by -+ * parsing DER-/PEM-encoded string. We would need another flag for that. -+ */ - void - ossl_pkey_check_public_key(const EVP_PKEY *pkey) - { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ if (EVP_PKEY_missing_parameters(pkey)) -+ ossl_raise(ePKeyError, "parameters missing"); -+#else - void *ptr; - const BIGNUM *n, *e, *pubkey; - -@@ -466,6 +476,7 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey) - return; - } - ossl_raise(ePKeyError, "public key missing"); -+#endif - } - - EVP_PKEY * - -From d6535d13d174cd87ae99f3e60e97f7a00e1474e5 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 12 Apr 2021 10:43:46 +0900 -Subject: [PATCH 8/8] pkey: use EVP_PKEY_CTX_new_from_name() on OpenSSL 3.0 - -Replace EVP_PKEY_CTX_new_id() with the new EVP_PKEY_CTX_new_from_name() -which takes the algorithm name in a string instead of in an NID. ---- - ext/openssl/ossl_pkey.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 09d45d85..2a4835a2 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -315,6 +315,11 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) - ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); - } - else { -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+ ctx = EVP_PKEY_CTX_new_from_name(NULL, StringValueCStr(alg), NULL); -+ if (!ctx) -+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_from_name"); -+#else - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng; - int pkey_id; -@@ -333,6 +338,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) - ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */); - if (!ctx) - ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id"); -+#endif - } - - if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) { diff --git a/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support.patch b/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support.patch deleted file mode 100644 index a780108..0000000 --- a/ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support.patch +++ /dev/null @@ -1,304 +0,0 @@ -From 8f948ed68a4ed6c05ff66d822711e3b70ae4bb3f Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 27 Sep 2021 13:32:03 +0900 -Subject: [PATCH 1/5] ext/openssl/ossl.h: add helper macros for - OpenSSL/LibreSSL versions - -Add following convenient macros: - - - OSSL_IS_LIBRESSL - - OSSL_OPENSSL_PREREQ(maj, min, pat) - - OSSL_LIBRESSL_PREREQ(maj, min, pat) ---- - ext/openssl/ossl.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h -index c20f506bda..a0cef29d74 100644 ---- a/ext/openssl/ossl.h -+++ b/ext/openssl/ossl.h -@@ -42,6 +42,18 @@ - #include - #include - -+#ifndef LIBRESSL_VERSION_NUMBER -+# define OSSL_IS_LIBRESSL 0 -+# define OSSL_OPENSSL_PREREQ(maj, min, pat) \ -+ (OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) -+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 -+#else -+# define OSSL_IS_LIBRESSL 1 -+# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 -+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ -+ (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) -+#endif -+ - /* - * Common Module - */ --- -2.32.0 - - -From bbf235091e49807ece8f3a3df95bbfcc9d3ab43d Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 22 Feb 2020 05:37:01 +0900 -Subject: [PATCH 2/5] ts: use TS_VERIFY_CTX_set_certs instead of - TS_VERIFY_CTS_set_certs - -OpenSSL 3.0 fixed the typo in the function name and replaced the -current 'CTS' version with a macro. ---- - ext/openssl/extconf.rb | 5 ++++- - ext/openssl/openssl_missing.h | 5 +++++ - ext/openssl/ossl_ts.c | 2 +- - 3 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 17d93443fc..09cae05b72 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -165,7 +165,7 @@ def find_openssl_library - have_func("TS_STATUS_INFO_get0_status") - have_func("TS_STATUS_INFO_get0_text") - have_func("TS_STATUS_INFO_get0_failure_info") --have_func("TS_VERIFY_CTS_set_certs") -+have_func("TS_VERIFY_CTS_set_certs(NULL, NULL)", "openssl/ts.h") - have_func("TS_VERIFY_CTX_set_store") - have_func("TS_VERIFY_CTX_add_flags") - have_func("TS_RESP_CTX_set_time_cb") -@@ -174,6 +174,9 @@ def find_openssl_library - - # added in 1.1.1 - have_func("EVP_PKEY_check") -+ -+# added in 3.0.0 -+have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") - - Logging::message "=== Checking done. ===\n" - -diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h -index e575415f49..fe486bcfcf 100644 ---- a/ext/openssl/openssl_missing.h -+++ b/ext/openssl/openssl_missing.h -@@ -236,4 +236,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec) - } while (0) - #endif - -+/* added in 3.0.0 */ -+#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS) -+# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts) -+#endif -+ - #endif /* _OSSL_OPENSSL_MISSING_H_ */ -diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c -index 692c0d620f..f1da7c1947 100644 ---- a/ext/openssl/ossl_ts.c -+++ b/ext/openssl/ossl_ts.c -@@ -820,7 +820,7 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) - X509_up_ref(cert); - } - -- TS_VERIFY_CTS_set_certs(ctx, x509inter); -+ TS_VERIFY_CTX_set_certs(ctx, x509inter); - TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); - TS_VERIFY_CTX_set_store(ctx, x509st); - --- -2.32.0 - - -From 5fba3bc1df93ab6abc3ea53be3393480f36ea259 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 19 Mar 2021 19:18:25 +0900 -Subject: [PATCH 3/5] ssl: use SSL_get_rbio() to check if SSL is started or not - -Use SSL_get_rbio() instead of SSL_get_fd(). SSL_get_fd() internally -calls SSL_get_rbio() and it's enough for our purpose. - -In OpenSSL 3.0, SSL_get_fd() leaves an entry in the OpenSSL error queue -if BIO has not been set up yet, and we would have to clean it up. ---- - ext/openssl/ossl_ssl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c -index 4b7efa39f5..ec430bfb0c 100644 ---- a/ext/openssl/ossl_ssl.c -+++ b/ext/openssl/ossl_ssl.c -@@ -1535,8 +1535,8 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) - static inline int - ssl_started(SSL *ssl) - { -- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */ -- return SSL_get_fd(ssl) >= 0; -+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */ -+ return SSL_get_rbio(ssl) != NULL; - } - - static void --- -2.32.0 - -From 0a253027e6be47c0b7fd8b664f1048f24d7ca657 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 22 Apr 2021 13:57:47 +0900 -Subject: [PATCH 4/5] digest: use EVP_MD_CTX_get0_md() instead of - EVP_MD_CTX_md() if exists - -The function was renamed in OpenSSL 3.0 due to the change of the -lifetime of EVP_MD objects. They are no longer necessarily statically -allocated and can be reference-counted -- when an EVP_MD_CTX is free'd, -the associated EVP_MD can also become inaccessible. - -Currently Ruby/OpenSSL only handles builtin algorithms, so no special -handling is needed except for adapting to the rename. ---- - ext/openssl/extconf.rb | 1 + - ext/openssl/openssl_missing.h | 4 ++++ - ext/openssl/ossl_digest.c | 6 +++--- - ext/openssl/ossl_hmac.c | 2 +- - 4 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 98f96afe..842b7f5b 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -177,6 +177,7 @@ def find_openssl_library - - # added in 3.0.0 - have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") -+have_func("EVP_MD_CTX_get0_md") - - Logging::message "=== Checking done. ===\n" - -diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h -index 1b1a54a8..64212349 100644 ---- a/ext/openssl/openssl_missing.h -+++ b/ext/openssl/openssl_missing.h -@@ -241,4 +241,8 @@ IMPL_PKEY_GETTER(EC_KEY, ec) - # define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts) - #endif - -+#ifndef HAVE_EVP_MD_CTX_GET0_MD -+# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) -+#endif -+ - #endif /* _OSSL_OPENSSL_MISSING_H_ */ -diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c -index b2506de7..fc326ec1 100644 ---- a/ext/openssl/ossl_digest.c -+++ b/ext/openssl/ossl_digest.c -@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj) - - GetDigest(obj, ctx); - -- md = EVP_MD_CTX_md(ctx); -+ md = EVP_MD_CTX_get0_md(ctx); - } - - return md; -@@ -176,7 +176,7 @@ ossl_digest_reset(VALUE self) - EVP_MD_CTX *ctx; - - GetDigest(self, ctx); -- if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { -+ if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); - } - -@@ -259,7 +259,7 @@ ossl_digest_name(VALUE self) - - GetDigest(self, ctx); - -- return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); -+ return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx))); - } - - /* -diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c -index a21db6c4..2642728b 100644 ---- a/ext/openssl/ossl_hmac.c -+++ b/ext/openssl/ossl_hmac.c -@@ -239,7 +239,7 @@ ossl_hmac_reset(VALUE self) - - GetHMAC(self, ctx); - pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); -- if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1) -+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) - ossl_raise(eHMACError, "EVP_DigestSignInit"); - - return self; - -From c106d888c62e44a11cdbba5e4d2d0cb837ec3e52 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 22 Jun 2021 18:50:17 +0900 -Subject: [PATCH 5/5] hmac: use EVP_MD_CTX_get_pkey_ctx() instead of - EVP_MD_CTX_pkey_ctx() - -OpenSSL 3.0 renamed EVP_MD_CTX_pkey_ctx() to include "get" in the -function name. Adjust compatibility macro so that we can use the new -function name for all OpenSSL 1.0.2-3.0. ---- - ext/openssl/extconf.rb | 1 + - ext/openssl/openssl_missing.h | 16 ++++++++++++---- - ext/openssl/ossl_hmac.c | 2 +- - 3 files changed, 14 insertions(+), 5 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 842b7f5b..d9d34b7c 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -178,6 +178,7 @@ def find_openssl_library - # added in 3.0.0 - have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") - have_func("EVP_MD_CTX_get0_md") -+have_func("EVP_MD_CTX_get_pkey_ctx") - - Logging::message "=== Checking done. ===\n" - -diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h -index 64212349..55c4f378 100644 ---- a/ext/openssl/openssl_missing.h -+++ b/ext/openssl/openssl_missing.h -@@ -42,10 +42,6 @@ int ossl_EC_curve_nist2nid(const char *); - # define EVP_MD_CTX_free EVP_MD_CTX_destroy - #endif - --#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX) --# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx --#endif -- - #if !defined(HAVE_X509_STORE_GET_EX_DATA) - # define X509_STORE_get_ex_data(x, idx) \ - CRYPTO_get_ex_data(&(x)->ex_data, (idx)) -@@ -245,4 +241,16 @@ IMPL_PKEY_GETTER(EC_KEY, ec) - # define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) - #endif - -+/* -+ * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to -+ * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0. -+ */ -+#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX -+# ifdef HAVE_EVP_MD_CTX_PKEY_CTX -+# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x) -+# else -+# define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx -+# endif -+#endif -+ - #endif /* _OSSL_OPENSSL_MISSING_H_ */ -diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c -index 2642728b..f89ff2f9 100644 ---- a/ext/openssl/ossl_hmac.c -+++ b/ext/openssl/ossl_hmac.c -@@ -238,7 +238,7 @@ ossl_hmac_reset(VALUE self) - EVP_PKEY *pkey; - - GetHMAC(self, ctx); -- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); -+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); - if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) - ossl_raise(eHMACError, "EVP_DigestSignInit"); - diff --git a/ruby-3.1.0-Properly-exclude-test-cases.patch b/ruby-3.1.0-Properly-exclude-test-cases.patch deleted file mode 100644 index ca2cd9b..0000000 --- a/ruby-3.1.0-Properly-exclude-test-cases.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 96684439e96aa92e10376b5be45f006772028295 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?V=C3=ADt=20Ondruch?= -Date: Thu, 21 Oct 2021 13:02:38 +0200 -Subject: [PATCH] Properly exclude test cases. - -Lets consider the following scenario: - -~~~ -irb(#):001:0> p suite -OpenSSL::TestEC -=> OpenSSL::TestEC - -irb(#):002:0> p all_test_methods -["test_ECPrivateKey", "test_ECPrivateKey_encrypted", "test_PUBKEY", "test_check_key", "test_derive_key", "test_dh_compute_key", "test_dsa_sign_asn1_FIPS186_3", "test_ec_group", "test_ec_key", "test_ec_point", "test_ec_point_add", "test_ec_point_mul", "test_generate", "test_marshal", "test_sign_verify", "test_sign_verify_raw"] -=> -["test_ECPrivateKey", - "test_ECPrivateKey_encrypted", - "test_PUBKEY", - "test_check_key", - "test_derive_key", - "test_dh_compute_key", - "test_dsa_sign_asn1_FIPS186_3", - "test_ec_group", - "test_ec_key", - "test_ec_point", - "test_ec_point_add", - "test_ec_point_mul", - "test_generate", - "test_marshal", - "test_sign_verify", - "test_sign_verify_raw"] - -irb(#):003:0> p filter -/\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/ -=> /\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/ - -irb(#):004:0> method = "test_check_key" -=> "test_check_key" -~~~ - -The intention here is to exclude the `test_check_key` test case. -Unfortunately this does not work as expected, because the negative filter -is never checked: - -~~~ - -irb(#):005:0> filter === method -=> true - -irb(#):006:0> filter === "#{suite}##{method}" -=> false - -irb(#):007:0> filter === method || filter === "#{suite}##{method}" -=> true -~~~ - -Therefore always filter against the fully qualified method name -`#{suite}##{method}`, which should provide the expected result. - -However, if plain string filter is used, keep checking also only the -method name. - -This resolves [Bug #16936]. ---- - tool/lib/minitest/unit.rb | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/tool/lib/minitest/unit.rb b/tool/lib/minitest/unit.rb -index c58a609bfa..d5af6cb906 100644 ---- a/tool/lib/minitest/unit.rb -+++ b/tool/lib/minitest/unit.rb -@@ -956,9 +956,15 @@ def _run_suite suite, type - - all_test_methods = suite.send "#{type}_methods" - -- filtered_test_methods = all_test_methods.find_all { |m| -- filter === m || filter === "#{suite}##{m}" -- } -+ filtered_test_methods = if Regexp === filter -+ all_test_methods.find_all { |m| -+ filter === "#{suite}##{m}" -+ } -+ else -+ all_test_methods.find_all {|m| -+ filter === m || filter === "#{suite}##{m}" -+ } -+ end - - leakchecker = LeakChecker.new - --- -2.32.0 - diff --git a/ruby-3.1.0-Refactor-PEM-DER-serialization-code.patch b/ruby-3.1.0-Refactor-PEM-DER-serialization-code.patch deleted file mode 100644 index d1de216..0000000 --- a/ruby-3.1.0-Refactor-PEM-DER-serialization-code.patch +++ /dev/null @@ -1,1450 +0,0 @@ -From 8b8e1d7f9b6b5a335864bbd0716df2af1ec41d91 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 16 Mar 2017 16:06:53 +0900 -Subject: [PATCH 1/5] pkey: simplify ossl_pkey_new() - -ossl_{rsa,dsa,dh,ec}_new() called from this function are not used -anywhere else. Inline them into pkey_new0() and reduce code -duplication. ---- - ext/openssl/ossl_pkey.c | 22 +++++++++------------- - ext/openssl/ossl_pkey.h | 3 --- - ext/openssl/ossl_pkey_dh.c | 21 --------------------- - ext/openssl/ossl_pkey_dsa.c | 21 --------------------- - ext/openssl/ossl_pkey_ec.c | 20 -------------------- - ext/openssl/ossl_pkey_rsa.c | 22 ---------------------- - 6 files changed, 9 insertions(+), 100 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 23204087ac..c6dbf57272 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -95,7 +95,7 @@ const rb_data_type_t ossl_evp_pkey_type = { - static VALUE - pkey_new0(EVP_PKEY *pkey) - { -- VALUE obj; -+ VALUE klass, obj; - int type; - - if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE) -@@ -103,26 +103,22 @@ pkey_new0(EVP_PKEY *pkey) - - switch (type) { - #if !defined(OPENSSL_NO_RSA) -- case EVP_PKEY_RSA: -- return ossl_rsa_new(pkey); -+ case EVP_PKEY_RSA: klass = cRSA; break; - #endif - #if !defined(OPENSSL_NO_DSA) -- case EVP_PKEY_DSA: -- return ossl_dsa_new(pkey); -+ case EVP_PKEY_DSA: klass = cDSA; break; - #endif - #if !defined(OPENSSL_NO_DH) -- case EVP_PKEY_DH: -- return ossl_dh_new(pkey); -+ case EVP_PKEY_DH: klass = cDH; break; - #endif - #if !defined(OPENSSL_NO_EC) -- case EVP_PKEY_EC: -- return ossl_ec_new(pkey); -+ case EVP_PKEY_EC: klass = cEC; break; - #endif -- default: -- obj = NewPKey(cPKey); -- SetPKey(obj, pkey); -- return obj; -+ default: klass = cPKey; break; - } -+ obj = NewPKey(klass); -+ SetPKey(obj, pkey); -+ return obj; - } - - VALUE -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index 0db59305f7..e363a261c2 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -56,7 +56,6 @@ void Init_ossl_pkey(void); - extern VALUE cRSA; - extern VALUE eRSAError; - --VALUE ossl_rsa_new(EVP_PKEY *); - void Init_ossl_rsa(void); - - /* -@@ -65,7 +64,6 @@ void Init_ossl_rsa(void); - extern VALUE cDSA; - extern VALUE eDSAError; - --VALUE ossl_dsa_new(EVP_PKEY *); - void Init_ossl_dsa(void); - - /* -@@ -74,7 +72,6 @@ void Init_ossl_dsa(void); - extern VALUE cDH; - extern VALUE eDHError; - --VALUE ossl_dh_new(EVP_PKEY *); - void Init_ossl_dh(void); - - /* -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index bf4e3f9322..dff69cfc33 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -54,27 +54,6 @@ dh_instance(VALUE klass, DH *dh) - return obj; - } - --VALUE --ossl_dh_new(EVP_PKEY *pkey) --{ -- VALUE obj; -- -- if (!pkey) { -- obj = dh_instance(cDH, DH_new()); -- } else { -- obj = NewPKey(cDH); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { -- ossl_raise(rb_eTypeError, "Not a DH key!"); -- } -- SetPKey(obj, pkey); -- } -- if (obj == Qfalse) { -- ossl_raise(eDHError, NULL); -- } -- -- return obj; --} -- - /* - * Private - */ -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index 431c20e05c..e9be9ac482 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -68,27 +68,6 @@ dsa_instance(VALUE klass, DSA *dsa) - return obj; - } - --VALUE --ossl_dsa_new(EVP_PKEY *pkey) --{ -- VALUE obj; -- -- if (!pkey) { -- obj = dsa_instance(cDSA, DSA_new()); -- } else { -- obj = NewPKey(cDSA); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { -- ossl_raise(rb_eTypeError, "Not a DSA key!"); -- } -- SetPKey(obj, pkey); -- } -- if (obj == Qfalse) { -- ossl_raise(eDSAError, NULL); -- } -- -- return obj; --} -- - /* - * Private - */ -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index fc2bc6c815..eabf495f19 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -84,26 +84,6 @@ static VALUE ec_instance(VALUE klass, EC_KEY *ec) - return obj; - } - --VALUE ossl_ec_new(EVP_PKEY *pkey) --{ -- VALUE obj; -- -- if (!pkey) { -- obj = ec_instance(cEC, EC_KEY_new()); -- } else { -- obj = NewPKey(cEC); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { -- ossl_raise(rb_eTypeError, "Not a EC key!"); -- } -- SetPKey(obj, pkey); -- } -- if (obj == Qfalse) { -- ossl_raise(eECError, NULL); -- } -- -- return obj; --} -- - /* - * Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String - * representing an OID. -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 761866c66a..c1ae44fe40 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -69,28 +69,6 @@ rsa_instance(VALUE klass, RSA *rsa) - return obj; - } - --VALUE --ossl_rsa_new(EVP_PKEY *pkey) --{ -- VALUE obj; -- -- if (!pkey) { -- obj = rsa_instance(cRSA, RSA_new()); -- } -- else { -- obj = NewPKey(cRSA); -- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { -- ossl_raise(rb_eTypeError, "Not a RSA key!"); -- } -- SetPKey(obj, pkey); -- } -- if (obj == Qfalse) { -- ossl_raise(eRSAError, NULL); -- } -- -- return obj; --} -- - /* - * Private - */ --- -2.32.0 - - -From 2b0d259ef7aae707922996d305675a68dad27abd Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 16 Mar 2017 16:09:35 +0900 -Subject: [PATCH 2/5] pkey: inline {rsa,dsa,dh,ec}_instance() - -Merge the code into the callers so that the wrapping Ruby object is -allocated before the raw key object is allocated. This prevents possible -memory leak on Ruby object allocation failure, and also reduces the -lines of code. ---- - ext/openssl/ossl_pkey_dh.c | 63 ++++++++++++---------------------- - ext/openssl/ossl_pkey_dsa.c | 68 ++++++++++++++----------------------- - ext/openssl/ossl_pkey_ec.c | 34 ++++--------------- - ext/openssl/ossl_pkey_rsa.c | 67 +++++++++++++----------------------- - 4 files changed, 76 insertions(+), 156 deletions(-) - -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index dff69cfc33..bc50e5566b 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -29,31 +29,6 @@ - VALUE cDH; - VALUE eDHError; - --/* -- * Public -- */ --static VALUE --dh_instance(VALUE klass, DH *dh) --{ -- EVP_PKEY *pkey; -- VALUE obj; -- -- if (!dh) { -- return Qfalse; -- } -- obj = NewPKey(klass); -- if (!(pkey = EVP_PKEY_new())) { -- return Qfalse; -- } -- if (!EVP_PKEY_assign_DH(pkey, dh)) { -- EVP_PKEY_free(pkey); -- return Qfalse; -- } -- SetPKey(obj, pkey); -- -- return obj; --} -- - /* - * Private - */ -@@ -84,7 +59,7 @@ dh_generate(int size, int gen) - if (!dh || !cb) { - DH_free(dh); - BN_GENCB_free(cb); -- return NULL; -+ ossl_raise(eDHError, "malloc failure"); - } - - if (rb_block_given_p()) -@@ -110,12 +85,12 @@ dh_generate(int size, int gen) - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } -- return NULL; -+ ossl_raise(eDHError, "DH_generate_parameters_ex"); - } - - if (!DH_generate_key(dh)) { - DH_free(dh); -- return NULL; -+ ossl_raise(eDHError, "DH_generate_key"); - } - - return dh; -@@ -136,6 +111,7 @@ dh_generate(int size, int gen) - static VALUE - ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) - { -+ EVP_PKEY *pkey; - DH *dh ; - int g = 2; - VALUE size, gen, obj; -@@ -143,13 +119,14 @@ ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) - if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { - g = NUM2INT(gen); - } -+ obj = rb_obj_alloc(klass); -+ GetPKey(obj, pkey); -+ - dh = dh_generate(NUM2INT(size), g); -- obj = dh_instance(klass, dh); -- if (obj == Qfalse) { -- DH_free(dh); -- ossl_raise(eDHError, NULL); -+ if (!EVP_PKEY_assign_DH(pkey, dh)) { -+ DH_free(dh); -+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); - } -- - return obj; - } - -@@ -195,9 +172,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self) - if (!NIL_P(gen)) { - g = NUM2INT(gen); - } -- if (!(dh = dh_generate(NUM2INT(arg), g))) { -- ossl_raise(eDHError, NULL); -- } -+ dh = dh_generate(NUM2INT(arg), g); - } - else { - arg = ossl_to_der_if_possible(arg); -@@ -434,17 +409,21 @@ ossl_dh_to_text(VALUE self) - static VALUE - ossl_dh_to_public_key(VALUE self) - { -+ EVP_PKEY *pkey; - DH *orig_dh, *dh; - VALUE obj; - -+ obj = rb_obj_alloc(rb_obj_class(self)); -+ GetPKey(obj, pkey); -+ - GetDH(self, orig_dh); -- dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */ -- obj = dh_instance(rb_obj_class(self), dh); -- if (obj == Qfalse) { -- DH_free(dh); -- ossl_raise(eDHError, NULL); -+ dh = DHparams_dup(orig_dh); -+ if (!dh) -+ ossl_raise(eDHError, "DHparams_dup"); -+ if (!EVP_PKEY_assign_DH(pkey, dh)) { -+ DH_free(dh); -+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); - } -- - return obj; - } - -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index e9be9ac482..c907f31c19 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -43,31 +43,6 @@ DSA_PRIVATE(VALUE obj, DSA *dsa) - VALUE cDSA; - VALUE eDSAError; - --/* -- * Public -- */ --static VALUE --dsa_instance(VALUE klass, DSA *dsa) --{ -- EVP_PKEY *pkey; -- VALUE obj; -- -- if (!dsa) { -- return Qfalse; -- } -- obj = NewPKey(klass); -- if (!(pkey = EVP_PKEY_new())) { -- return Qfalse; -- } -- if (!EVP_PKEY_assign_DSA(pkey, dsa)) { -- EVP_PKEY_free(pkey); -- return Qfalse; -- } -- SetPKey(obj, pkey); -- -- return obj; --} -- - /* - * Private - */ -@@ -100,9 +75,9 @@ dsa_generate(int size) - unsigned long h; - - if (!dsa || !cb) { -- DSA_free(dsa); -- BN_GENCB_free(cb); -- return NULL; -+ DSA_free(dsa); -+ BN_GENCB_free(cb); -+ ossl_raise(eDSAError, "malloc failure"); - } - - if (rb_block_given_p()) -@@ -132,12 +107,12 @@ dsa_generate(int size) - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } -- return NULL; -+ ossl_raise(eDSAError, "DSA_generate_parameters_ex"); - } - - if (!DSA_generate_key(dsa)) { -- DSA_free(dsa); -- return NULL; -+ DSA_free(dsa); -+ ossl_raise(eDSAError, "DSA_generate_key"); - } - - return dsa; -@@ -157,14 +132,18 @@ dsa_generate(int size) - static VALUE - ossl_dsa_s_generate(VALUE klass, VALUE size) - { -- DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */ -- VALUE obj = dsa_instance(klass, dsa); -+ EVP_PKEY *pkey; -+ DSA *dsa; -+ VALUE obj; - -- if (obj == Qfalse) { -- DSA_free(dsa); -- ossl_raise(eDSAError, NULL); -- } -+ obj = rb_obj_alloc(klass); -+ GetPKey(obj, pkey); - -+ dsa = dsa_generate(NUM2INT(size)); -+ if (!EVP_PKEY_assign_DSA(pkey, dsa)) { -+ DSA_free(dsa); -+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); -+ } - return obj; - } - -@@ -460,20 +439,23 @@ ossl_dsa_to_text(VALUE self) - static VALUE - ossl_dsa_to_public_key(VALUE self) - { -- EVP_PKEY *pkey; -+ EVP_PKEY *pkey, *pkey_new; - DSA *dsa; - VALUE obj; - - GetPKeyDSA(self, pkey); -- /* err check performed by dsa_instance */ -+ obj = rb_obj_alloc(rb_obj_class(self)); -+ GetPKey(obj, pkey_new); -+ - #define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \ - (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa)) - dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey)); - #undef DSAPublicKey_dup -- obj = dsa_instance(rb_obj_class(self), dsa); -- if (obj == Qfalse) { -- DSA_free(dsa); -- ossl_raise(eDSAError, NULL); -+ if (!dsa) -+ ossl_raise(eDSAError, "DSAPublicKey_dup"); -+ if (!EVP_PKEY_assign_DSA(pkey_new, dsa)) { -+ DSA_free(dsa); -+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); - } - return obj; - } -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index eabf495f19..aec9d1e60f 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -63,27 +63,6 @@ static ID id_i_group; - static VALUE ec_group_new(const EC_GROUP *group); - static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group); - --static VALUE ec_instance(VALUE klass, EC_KEY *ec) --{ -- EVP_PKEY *pkey; -- VALUE obj; -- -- if (!ec) { -- return Qfalse; -- } -- obj = NewPKey(klass); -- if (!(pkey = EVP_PKEY_new())) { -- return Qfalse; -- } -- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { -- EVP_PKEY_free(pkey); -- return Qfalse; -- } -- SetPKey(obj, pkey); -- -- return obj; --} -- - /* - * Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String - * representing an OID. -@@ -130,17 +109,18 @@ ec_key_new_from_group(VALUE arg) - static VALUE - ossl_ec_key_s_generate(VALUE klass, VALUE arg) - { -+ EVP_PKEY *pkey; - EC_KEY *ec; - VALUE obj; - -- ec = ec_key_new_from_group(arg); -+ obj = rb_obj_alloc(klass); -+ GetPKey(obj, pkey); - -- obj = ec_instance(klass, ec); -- if (obj == Qfalse) { -- EC_KEY_free(ec); -- ossl_raise(eECError, NULL); -+ ec = ec_key_new_from_group(arg); -+ if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { -+ EC_KEY_free(ec); -+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); - } -- - if (!EC_KEY_generate_key(ec)) - ossl_raise(eECError, "EC_KEY_generate_key"); - -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index c1ae44fe40..fbdb9c8960 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -44,31 +44,6 @@ RSA_PRIVATE(VALUE obj, RSA *rsa) - VALUE cRSA; - VALUE eRSAError; - --/* -- * Public -- */ --static VALUE --rsa_instance(VALUE klass, RSA *rsa) --{ -- EVP_PKEY *pkey; -- VALUE obj; -- -- if (!rsa) { -- return Qfalse; -- } -- obj = NewPKey(klass); -- if (!(pkey = EVP_PKEY_new())) { -- return Qfalse; -- } -- if (!EVP_PKEY_assign_RSA(pkey, rsa)) { -- EVP_PKEY_free(pkey); -- return Qfalse; -- } -- SetPKey(obj, pkey); -- -- return obj; --} -- - /* - * Private - */ -@@ -102,7 +77,7 @@ rsa_generate(int size, unsigned long exp) - RSA_free(rsa); - BN_free(e); - BN_GENCB_free(cb); -- return NULL; -+ ossl_raise(eRSAError, "malloc failure"); - } - for (i = 0; i < (int)sizeof(exp) * 8; ++i) { - if (exp & (1UL << i)) { -@@ -110,7 +85,7 @@ rsa_generate(int size, unsigned long exp) - BN_free(e); - RSA_free(rsa); - BN_GENCB_free(cb); -- return NULL; -+ ossl_raise(eRSAError, "BN_set_bit"); - } - } - } -@@ -139,7 +114,7 @@ rsa_generate(int size, unsigned long exp) - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } -- return NULL; -+ ossl_raise(eRSAError, "RSA_generate_key_ex"); - } - - return rsa; -@@ -158,26 +133,26 @@ static VALUE - ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) - { - /* why does this method exist? why can't initialize take an optional exponent? */ -+ EVP_PKEY *pkey; - RSA *rsa; - VALUE size, exp; - VALUE obj; - - rb_scan_args(argc, argv, "11", &size, &exp); -+ obj = rb_obj_alloc(klass); -+ GetPKey(obj, pkey); - -- rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); /* err handled by rsa_instance */ -- obj = rsa_instance(klass, rsa); -- -- if (obj == Qfalse) { -- RSA_free(rsa); -- ossl_raise(eRSAError, NULL); -+ rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); -+ if (!EVP_PKEY_assign_RSA(pkey, rsa)) { -+ RSA_free(rsa); -+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); - } -- - return obj; - } - - /* - * call-seq: -- * RSA.new(key_size) => RSA instance -+ * RSA.new(size [, exponent]) => RSA instance - * RSA.new(encoded_key) => RSA instance - * RSA.new(encoded_key, pass_phrase) => RSA instance - * -@@ -206,10 +181,11 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { - rsa = RSA_new(); -+ if (!rsa) -+ ossl_raise(eRSAError, "RSA_new"); - } - else if (RB_INTEGER_TYPE_P(arg)) { - rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass)); -- if (!rsa) ossl_raise(eRSAError, NULL); - } - else { - pass = ossl_pem_passwd_value(pass); -@@ -243,7 +219,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); -- ossl_raise(eRSAError, NULL); -+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); - } - - return self; -@@ -787,17 +763,20 @@ ossl_rsa_to_text(VALUE self) - static VALUE - ossl_rsa_to_public_key(VALUE self) - { -- EVP_PKEY *pkey; -+ EVP_PKEY *pkey, *pkey_new; - RSA *rsa; - VALUE obj; - - GetPKeyRSA(self, pkey); -- /* err check performed by rsa_instance */ -+ obj = rb_obj_alloc(rb_obj_class(self)); -+ GetPKey(obj, pkey_new); -+ - rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey)); -- obj = rsa_instance(rb_obj_class(self), rsa); -- if (obj == Qfalse) { -- RSA_free(rsa); -- ossl_raise(eRSAError, NULL); -+ if (!rsa) -+ ossl_raise(eRSAError, "RSAPublicKey_dup"); -+ if (!EVP_PKEY_assign_RSA(pkey_new, rsa)) { -+ RSA_free(rsa); -+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); - } - return obj; - } --- -2.32.0 - - -From 1e1fedc6c2c9d42bc76b5a24bf0f39c8101f8d53 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 18 Mar 2017 17:26:33 +0900 -Subject: [PATCH 3/5] pkey: have PKey.read parse PEM-encoded DHParameter - -Try PEM_read_bio_Parameters(). Only PEM format is supported at the -moment since corresponding d2i_* functions are not provided by OpenSSL. ---- - ext/openssl/ossl_pkey.c | 3 +++ - test/openssl/test_pkey_dh.rb | 2 ++ - test/openssl/utils.rb | 3 --- - 3 files changed, 5 insertions(+), 3 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index c6dbf57272..a00d66aada 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -178,6 +178,9 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) - OSSL_BIO_reset(bio); - if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) - goto ok; -+ OSSL_BIO_reset(bio); -+ if ((pkey = PEM_read_bio_Parameters(bio, NULL))) -+ goto ok; - - BIO_free(bio); - ossl_raise(ePKeyError, "Could not parse PKey"); -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index fd2c7a66a9..4a05626a12 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -36,6 +36,8 @@ def test_DHparams - EOF - key = OpenSSL::PKey::DH.new(pem) - assert_same_dh dup_public(dh1024), key -+ key = OpenSSL::PKey.read(pem) -+ assert_same_dh dup_public(dh1024), key - - assert_equal asn1.to_der, dh1024.to_der - assert_equal pem, dh1024.export -diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb -index 3776fbac4e..c1d737b2ab 100644 ---- a/test/openssl/utils.rb -+++ b/test/openssl/utils.rb -@@ -42,9 +42,6 @@ module Fixtures - - def pkey(name) - OpenSSL::PKey.read(read_file("pkey", name)) -- rescue OpenSSL::PKey::PKeyError -- # TODO: DH parameters can be read by OpenSSL::PKey.read atm -- OpenSSL::PKey::DH.new(read_file("pkey", name)) - end - - def read_file(category, name) --- -2.32.0 - - -From 70655b40a980dad36dfb3054d309f6484e2a70b7 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Tue, 13 Jun 2017 23:39:41 +0900 -Subject: [PATCH 4/5] pkey: refactor DER/PEM-encoded string parsing code - -Export the flow used by OpenSSL::PKey.read and let the subclasses call -it before attempting other formats. ---- - ext/openssl/ossl_pkey.c | 57 +++++++++++++++++++++---------------- - ext/openssl/ossl_pkey.h | 1 + - ext/openssl/ossl_pkey_dsa.c | 37 +++++++++++------------- - ext/openssl/ossl_pkey_ec.c | 29 +++++++------------ - ext/openssl/ossl_pkey_rsa.c | 26 ++++++++--------- - 5 files changed, 73 insertions(+), 77 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index a00d66aada..47ddd0f014 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -136,6 +136,35 @@ ossl_pkey_new(EVP_PKEY *pkey) - return obj; - } - -+EVP_PKEY * -+ossl_pkey_read_generic(BIO *bio, VALUE pass) -+{ -+ void *ppass = (void *)pass; -+ EVP_PKEY *pkey; -+ -+ if ((pkey = d2i_PrivateKey_bio(bio, NULL))) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass))) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if ((pkey = d2i_PUBKEY_bio(bio, NULL))) -+ goto out; -+ OSSL_BIO_reset(bio); -+ /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */ -+ if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, ppass))) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if ((pkey = PEM_read_bio_Parameters(bio, NULL))) -+ goto out; -+ -+ out: -+ return pkey; -+} -+ - /* - * call-seq: - * OpenSSL::PKey.read(string [, pwd ]) -> PKey -@@ -160,33 +189,11 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) - VALUE data, pass; - - rb_scan_args(argc, argv, "11", &data, &pass); -- pass = ossl_pem_passwd_value(pass); -- - bio = ossl_obj2bio(&data); -- if ((pkey = d2i_PrivateKey_bio(bio, NULL))) -- goto ok; -- OSSL_BIO_reset(bio); -- if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) -- goto ok; -- OSSL_BIO_reset(bio); -- if ((pkey = d2i_PUBKEY_bio(bio, NULL))) -- goto ok; -- OSSL_BIO_reset(bio); -- /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */ -- if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) -- goto ok; -- OSSL_BIO_reset(bio); -- if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) -- goto ok; -- OSSL_BIO_reset(bio); -- if ((pkey = PEM_read_bio_Parameters(bio, NULL))) -- goto ok; -- -- BIO_free(bio); -- ossl_raise(ePKeyError, "Could not parse PKey"); -- --ok: -+ pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass)); - BIO_free(bio); -+ if (!pkey) -+ ossl_raise(ePKeyError, "Could not parse PKey"); - return ossl_pkey_new(pkey); - } - -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index e363a261c2..895927e3fb 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -45,6 +45,7 @@ void ossl_generate_cb_stop(void *ptr); - - VALUE ossl_pkey_new(EVP_PKEY *); - void ossl_pkey_check_public_key(const EVP_PKEY *); -+EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); - EVP_PKEY *GetPKeyPtr(VALUE); - EVP_PKEY *DupPKeyPtr(VALUE); - EVP_PKEY *GetPrivPKeyPtr(VALUE); -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index c907f31c19..56f58559ed 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -170,37 +170,34 @@ ossl_dsa_s_generate(VALUE klass, VALUE size) - static VALUE - ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) - { -- EVP_PKEY *pkey; -- DSA *dsa; -+ EVP_PKEY *pkey, *tmp; -+ DSA *dsa = NULL; - BIO *in; - VALUE arg, pass; - - GetPKey(self, pkey); -- if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { -+ rb_scan_args(argc, argv, "02", &arg, &pass); -+ if (argc == 0) { - dsa = DSA_new(); -+ if (!dsa) -+ ossl_raise(eDSAError, "DSA_new"); - } -- else if (RB_INTEGER_TYPE_P(arg)) { -- if (!(dsa = dsa_generate(NUM2INT(arg)))) { -- ossl_raise(eDSAError, NULL); -- } -+ else if (argc == 1 && RB_INTEGER_TYPE_P(arg)) { -+ dsa = dsa_generate(NUM2INT(arg)); - } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); -- dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); -- if (!dsa) { -- OSSL_BIO_reset(in); -- dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); -- } -- if (!dsa) { -- OSSL_BIO_reset(in); -- dsa = d2i_DSAPrivateKey_bio(in, NULL); -- } -- if (!dsa) { -- OSSL_BIO_reset(in); -- dsa = d2i_DSA_PUBKEY_bio(in, NULL); -- } -+ -+ tmp = ossl_pkey_read_generic(in, pass); -+ if (tmp) { -+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA) -+ rb_raise(eDSAError, "incorrect pkey type: %s", -+ OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -+ dsa = EVP_PKEY_get1_DSA(tmp); -+ EVP_PKEY_free(tmp); -+ } - if (!dsa) { - OSSL_BIO_reset(in); - #define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index aec9d1e60f..ca8f5c6e4e 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -162,24 +162,17 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) - } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - ec = ec_key_new_from_group(arg); - } else { -- BIO *in; -- -- pass = ossl_pem_passwd_value(pass); -- in = ossl_obj2bio(&arg); -- -- ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); -- if (!ec) { -- OSSL_BIO_reset(in); -- ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass); -- } -- if (!ec) { -- OSSL_BIO_reset(in); -- ec = d2i_ECPrivateKey_bio(in, NULL); -- } -- if (!ec) { -- OSSL_BIO_reset(in); -- ec = d2i_EC_PUBKEY_bio(in, NULL); -- } -+ BIO *in = ossl_obj2bio(&arg); -+ EVP_PKEY *tmp; -+ pass = ossl_pem_passwd_value(pass); -+ tmp = ossl_pkey_read_generic(in, pass); -+ if (tmp) { -+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC) -+ rb_raise(eECError, "incorrect pkey type: %s", -+ OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -+ ec = EVP_PKEY_get1_EC_KEY(tmp); -+ EVP_PKEY_free(tmp); -+ } - BIO_free(in); - - if (!ec) { -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index fbdb9c8960..8415121c7d 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -179,7 +179,8 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - VALUE arg, pass; - - GetPKey(self, pkey); -- if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { -+ rb_scan_args(argc, argv, "02", &arg, &pass); -+ if (argc == 0) { - rsa = RSA_new(); - if (!rsa) - ossl_raise(eRSAError, "RSA_new"); -@@ -191,19 +192,15 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); -- rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); -- if (!rsa) { -- OSSL_BIO_reset(in); -- rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); -- } -- if (!rsa) { -- OSSL_BIO_reset(in); -- rsa = d2i_RSAPrivateKey_bio(in, NULL); -- } -- if (!rsa) { -- OSSL_BIO_reset(in); -- rsa = d2i_RSA_PUBKEY_bio(in, NULL); -- } -+ -+ tmp = ossl_pkey_read_generic(in, pass); -+ if (tmp) { -+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA) -+ rb_raise(eRSAError, "incorrect pkey type: %s", -+ OBJ_nid2sn(EVP_PKEY_base_id(tmp))); -+ rsa = EVP_PKEY_get1_RSA(tmp); -+ EVP_PKEY_free(tmp); -+ } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); -@@ -214,6 +211,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - } - BIO_free(in); - if (!rsa) { -+ ossl_clear_error(); - ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); - } - } --- -2.32.0 - - -From eacc680b1efc82935efc945bbe23c9073f17f440 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 14 Jun 2017 00:25:43 +0900 -Subject: [PATCH 5/5] pkey: refactor #export/#to_pem and #to_der - -Add ossl_pkey_export_traditional() and ossl_pkey_export_spki() helper -functions, and use them. This reduces code duplication. ---- - ext/openssl/ossl_pkey.c | 54 +++++++++++++++++++++-- - ext/openssl/ossl_pkey.h | 14 ++++++ - ext/openssl/ossl_pkey_dsa.c | 49 +++------------------ - ext/openssl/ossl_pkey_ec.c | 86 ++++++++----------------------------- - ext/openssl/ossl_pkey_rsa.c | 84 +++++++++++------------------------- - 5 files changed, 114 insertions(+), 173 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 47ddd0f014..610a83fd2d 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -341,6 +341,52 @@ ossl_pkey_inspect(VALUE self) - OBJ_nid2sn(nid)); - } - -+VALUE -+ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) -+{ -+ EVP_PKEY *pkey; -+ VALUE cipher, pass; -+ const EVP_CIPHER *enc = NULL; -+ BIO *bio; -+ -+ GetPKey(self, pkey); -+ rb_scan_args(argc, argv, "02", &cipher, &pass); -+ if (!NIL_P(cipher)) { -+ enc = ossl_evp_get_cipherbyname(cipher); -+ pass = ossl_pem_passwd_value(pass); -+ } -+ -+ bio = BIO_new(BIO_s_mem()); -+ if (!bio) -+ ossl_raise(ePKeyError, "BIO_new"); -+ if (to_der) { -+ if (!i2d_PrivateKey_bio(bio, pkey)) { -+ BIO_free(bio); -+ ossl_raise(ePKeyError, "i2d_PrivateKey_bio"); -+ } -+ } -+ else { -+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) -+ if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, -+ ossl_pem_passwd_cb, -+ (void *)pass)) { -+#else -+ char pem_str[80]; -+ const char *aname; -+ -+ EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &aname, pkey->ameth); -+ snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY", aname); -+ if (!PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, pem_str, bio, -+ pkey, enc, NULL, 0, ossl_pem_passwd_cb, -+ (void *)pass)) { -+#endif -+ BIO_free(bio); -+ ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional"); -+ } -+ } -+ return ossl_membio2str(bio); -+} -+ - static VALUE - do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der) - { -@@ -410,8 +456,8 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) - return do_pkcs8_export(argc, argv, self, 0); - } - --static VALUE --do_spki_export(VALUE self, int to_der) -+VALUE -+ossl_pkey_export_spki(VALUE self, int to_der) - { - EVP_PKEY *pkey; - BIO *bio; -@@ -444,7 +490,7 @@ do_spki_export(VALUE self, int to_der) - static VALUE - ossl_pkey_public_to_der(VALUE self) - { -- return do_spki_export(self, 1); -+ return ossl_pkey_export_spki(self, 1); - } - - /* -@@ -456,7 +502,7 @@ ossl_pkey_public_to_der(VALUE self) - static VALUE - ossl_pkey_public_to_pem(VALUE self) - { -- return do_spki_export(self, 0); -+ return ossl_pkey_export_spki(self, 0); - } - - /* -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index 895927e3fb..7dbaed47bc 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -49,6 +49,20 @@ EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); - EVP_PKEY *GetPKeyPtr(VALUE); - EVP_PKEY *DupPKeyPtr(VALUE); - EVP_PKEY *GetPrivPKeyPtr(VALUE); -+ -+/* -+ * Serializes _self_ in X.509 SubjectPublicKeyInfo format and returns the -+ * resulting String. Sub-classes use this when overriding #to_der. -+ */ -+VALUE ossl_pkey_export_spki(VALUE self, int to_der); -+/* -+ * Serializes the private key _self_ in the traditional private key format -+ * and returns the resulting String. Sub-classes use this when overriding -+ * #to_der. -+ */ -+VALUE ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, -+ int to_der); -+ - void Init_ossl_pkey(void); - - /* -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index 56f58559ed..0e68f7f27f 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -296,34 +296,12 @@ static VALUE - ossl_dsa_export(int argc, VALUE *argv, VALUE self) - { - DSA *dsa; -- BIO *out; -- const EVP_CIPHER *ciph = NULL; -- VALUE cipher, pass, str; - - GetDSA(self, dsa); -- rb_scan_args(argc, argv, "02", &cipher, &pass); -- if (!NIL_P(cipher)) { -- ciph = ossl_evp_get_cipherbyname(cipher); -- pass = ossl_pem_passwd_value(pass); -- } -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eDSAError, NULL); -- } -- if (DSA_HAS_PRIVATE(dsa)) { -- if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0, -- ossl_pem_passwd_cb, (void *)pass)){ -- BIO_free(out); -- ossl_raise(eDSAError, NULL); -- } -- } else { -- if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) { -- BIO_free(out); -- ossl_raise(eDSAError, NULL); -- } -- } -- str = ossl_membio2str(out); -- -- return str; -+ if (DSA_HAS_PRIVATE(dsa)) -+ return ossl_pkey_export_traditional(argc, argv, self, 0); -+ else -+ return ossl_pkey_export_spki(self, 0); - } - - /* -@@ -337,25 +315,12 @@ static VALUE - ossl_dsa_to_der(VALUE self) - { - DSA *dsa; -- int (*i2d_func)(DSA *, unsigned char **); -- unsigned char *p; -- long len; -- VALUE str; - - GetDSA(self, dsa); -- if(DSA_HAS_PRIVATE(dsa)) -- i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey; -+ if (DSA_HAS_PRIVATE(dsa)) -+ return ossl_pkey_export_traditional(0, NULL, self, 1); - else -- i2d_func = i2d_DSA_PUBKEY; -- if((len = i2d_func(dsa, NULL)) <= 0) -- ossl_raise(eDSAError, NULL); -- str = rb_str_new(0, len); -- p = (unsigned char *)RSTRING_PTR(str); -- if(i2d_func(dsa, &p) < 0) -- ossl_raise(eDSAError, NULL); -- ossl_str_adjust(str, p); -- -- return str; -+ return ossl_pkey_export_spki(self, 1); - } - - -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index ca8f5c6e4e..6fe2533e2a 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -141,7 +141,7 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) - static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; -- EC_KEY *ec; -+ EC_KEY *ec = NULL; - VALUE arg, pass; - - GetPKey(self, pkey); -@@ -378,66 +378,6 @@ static VALUE ossl_ec_key_is_private(VALUE self) - return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse; - } - --static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format) --{ -- EC_KEY *ec; -- BIO *out; -- int i = -1; -- int private = 0; -- VALUE str; -- const EVP_CIPHER *cipher = NULL; -- -- GetEC(self, ec); -- -- if (EC_KEY_get0_public_key(ec) == NULL) -- ossl_raise(eECError, "can't export - no public key set"); -- -- if (EC_KEY_check_key(ec) != 1) -- ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); -- -- if (EC_KEY_get0_private_key(ec)) -- private = 1; -- -- if (!NIL_P(ciph)) { -- cipher = ossl_evp_get_cipherbyname(ciph); -- pass = ossl_pem_passwd_value(pass); -- } -- -- if (!(out = BIO_new(BIO_s_mem()))) -- ossl_raise(eECError, "BIO_new(BIO_s_mem())"); -- -- switch(format) { -- case EXPORT_PEM: -- if (private) { -- i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass); -- } else { -- i = PEM_write_bio_EC_PUBKEY(out, ec); -- } -- -- break; -- case EXPORT_DER: -- if (private) { -- i = i2d_ECPrivateKey_bio(out, ec); -- } else { -- i = i2d_EC_PUBKEY_bio(out, ec); -- } -- -- break; -- default: -- BIO_free(out); -- ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); -- } -- -- if (i != 1) { -- BIO_free(out); -- ossl_raise(eECError, "outlen=%d", i); -- } -- -- str = ossl_membio2str(out); -- -- return str; --} -- - /* - * call-seq: - * key.export([cipher, pass_phrase]) => String -@@ -448,11 +388,16 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma - * instance. Note that encryption will only be effective for a private key, - * public keys will always be encoded in plain text. - */ --static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self) -+static VALUE -+ossl_ec_key_export(int argc, VALUE *argv, VALUE self) - { -- VALUE cipher, passwd; -- rb_scan_args(argc, argv, "02", &cipher, &passwd); -- return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM); -+ EC_KEY *ec; -+ -+ GetEC(self, ec); -+ if (EC_KEY_get0_private_key(ec)) -+ return ossl_pkey_export_traditional(argc, argv, self, 0); -+ else -+ return ossl_pkey_export_spki(self, 0); - } - - /* -@@ -461,9 +406,16 @@ static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self) - * - * See the OpenSSL documentation for i2d_ECPrivateKey_bio() - */ --static VALUE ossl_ec_key_to_der(VALUE self) -+static VALUE -+ossl_ec_key_to_der(VALUE self) - { -- return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER); -+ EC_KEY *ec; -+ -+ GetEC(self, ec); -+ if (EC_KEY_get0_private_key(ec)) -+ return ossl_pkey_export_traditional(0, NULL, self, 1); -+ else -+ return ossl_pkey_export_spki(self, 1); - } - - /* -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 8415121c7d..3c298a2aea 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -173,8 +173,8 @@ ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) - static VALUE - ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - { -- EVP_PKEY *pkey; -- RSA *rsa; -+ EVP_PKEY *pkey, *tmp; -+ RSA *rsa = NULL; - BIO *in; - VALUE arg, pass; - -@@ -279,6 +279,21 @@ ossl_rsa_is_private(VALUE self) - return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse; - } - -+static int -+can_export_rsaprivatekey(VALUE self) -+{ -+ RSA *rsa; -+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; -+ -+ GetRSA(self, rsa); -+ -+ RSA_get0_key(rsa, &n, &e, &d); -+ RSA_get0_factors(rsa, &p, &q); -+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); -+ -+ return n && e && d && p && q && dmp1 && dmq1 && iqmp; -+} -+ - /* - * call-seq: - * rsa.export([cipher, pass_phrase]) => PEM-format String -@@ -292,41 +307,10 @@ ossl_rsa_is_private(VALUE self) - static VALUE - ossl_rsa_export(int argc, VALUE *argv, VALUE self) - { -- RSA *rsa; -- const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; -- BIO *out; -- const EVP_CIPHER *ciph = NULL; -- VALUE cipher, pass, str; -- -- GetRSA(self, rsa); -- -- rb_scan_args(argc, argv, "02", &cipher, &pass); -- -- if (!NIL_P(cipher)) { -- ciph = ossl_evp_get_cipherbyname(cipher); -- pass = ossl_pem_passwd_value(pass); -- } -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eRSAError, NULL); -- } -- RSA_get0_key(rsa, &n, &e, &d); -- RSA_get0_factors(rsa, &p, &q); -- RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); -- if (n && e && d && p && q && dmp1 && dmq1 && iqmp) { -- if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0, -- ossl_pem_passwd_cb, (void *)pass)) { -- BIO_free(out); -- ossl_raise(eRSAError, NULL); -- } -- } else { -- if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) { -- BIO_free(out); -- ossl_raise(eRSAError, NULL); -- } -- } -- str = ossl_membio2str(out); -- -- return str; -+ if (can_export_rsaprivatekey(self)) -+ return ossl_pkey_export_traditional(argc, argv, self, 0); -+ else -+ return ossl_pkey_export_spki(self, 0); - } - - /* -@@ -338,30 +322,10 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self) - static VALUE - ossl_rsa_to_der(VALUE self) - { -- RSA *rsa; -- const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; -- int (*i2d_func)(const RSA *, unsigned char **); -- unsigned char *ptr; -- long len; -- VALUE str; -- -- GetRSA(self, rsa); -- RSA_get0_key(rsa, &n, &e, &d); -- RSA_get0_factors(rsa, &p, &q); -- RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); -- if (n && e && d && p && q && dmp1 && dmq1 && iqmp) -- i2d_func = i2d_RSAPrivateKey; -+ if (can_export_rsaprivatekey(self)) -+ return ossl_pkey_export_traditional(0, NULL, self, 1); - else -- i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY; -- if((len = i2d_func(rsa, NULL)) <= 0) -- ossl_raise(eRSAError, NULL); -- str = rb_str_new(0, len); -- ptr = (unsigned char *)RSTRING_PTR(str); -- if(i2d_func(rsa, &ptr) < 0) -- ossl_raise(eRSAError, NULL); -- ossl_str_adjust(str, ptr); -- -- return str; -+ return ossl_pkey_export_spki(self, 1); - } - - /* --- -2.32.0 - diff --git a/ruby-3.1.0-Support-GCCs-DWARF-5.patch b/ruby-3.1.0-Support-GCCs-DWARF-5.patch deleted file mode 100644 index d9b434a..0000000 --- a/ruby-3.1.0-Support-GCCs-DWARF-5.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 3b91792d3d644d6d6b0059cb315c9fe5d3626bab Mon Sep 17 00:00:00 2001 -From: Yusuke Endoh -Date: Sat, 6 Mar 2021 00:03:57 +0900 -Subject: [PATCH] Support GCC's DWARF 5 [Bug #17585] - -Co-Authored-By: xtkoba (Tee KOBAYASHI) ---- - addr2line.c | 119 ++++++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 97 insertions(+), 22 deletions(-) - -diff --git a/addr2line.c b/addr2line.c -index 0029cffbca..855efb40d4 100644 ---- a/addr2line.c -+++ b/addr2line.c -@@ -159,11 +159,12 @@ typedef struct obj_info { - struct dwarf_section debug_info; - struct dwarf_section debug_line; - struct dwarf_section debug_ranges; -+ struct dwarf_section debug_rnglists; - struct dwarf_section debug_str; - struct obj_info *next; - } obj_info_t; - --#define DWARF_SECTION_COUNT 5 -+#define DWARF_SECTION_COUNT 6 - - static struct dwarf_section * - obj_dwarf_section_at(obj_info_t *obj, int n) -@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n) - &obj->debug_info, - &obj->debug_line, - &obj->debug_ranges, -+ &obj->debug_rnglists, - &obj->debug_str - }; - if (n < 0 || DWARF_SECTION_COUNT <= n) { -@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line, - FILL_LINE(); - break; - case DW_LNS_advance_pc: -- a = uleb128((char **)&p); -+ a = uleb128((char **)&p) * header.minimum_instruction_length; - addr += a; - break; - case DW_LNS_advance_line: { -@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line, - /* isa = (unsigned int)*/(void)uleb128((char **)&p); - break; - case 0: -- a = *(unsigned char *)p++; -+ a = uleb128((char **)&p); - op = *p++; - switch (op) { - case DW_LNE_end_sequence: -@@ -808,6 +810,18 @@ enum - DW_FORM_addrx4 = 0x2c - }; - -+/* Range list entry encodings */ -+enum { -+ DW_RLE_end_of_list = 0x00, -+ DW_RLE_base_addressx = 0x01, -+ DW_RLE_startx_endx = 0x02, -+ DW_RLE_startx_length = 0x03, -+ DW_RLE_offset_pair = 0x04, -+ DW_RLE_base_address = 0x05, -+ DW_RLE_start_end = 0x06, -+ DW_RLE_start_length = 0x07 -+}; -+ - enum { - VAL_none = 0, - VAL_cstr = 1, -@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj) - reader->current_low_pc = 0; - } - -+static void -+di_skip_die_attributes(char **p) -+{ -+ for (;;) { -+ uint64_t at = uleb128(p); -+ uint64_t form = uleb128(p); -+ if (!at && !form) break; -+ switch (form) { -+ default: -+ break; -+ case DW_FORM_implicit_const: -+ sleb128(p); -+ break; -+ } -+ } -+} -+ - static void - di_read_debug_abbrev_cu(DebugInfoReader *reader) - { -@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader) - prev = abbrev_number; - uleb128(&p); /* tag */ - p++; /* has_children */ -- /* skip content */ -- for (;;) { -- uint64_t at = uleb128(&p); -- uint64_t form = uleb128(&p); -- if (!at && !form) break; -- } -+ di_skip_die_attributes(&p); - } - } - -@@ -1244,12 +1270,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) - /* skip 255th record */ - uleb128(&p); /* tag */ - p++; /* has_children */ -- /* skip content */ -- for (;;) { -- uint64_t at = uleb128(&p); -- uint64_t form = uleb128(&p); -- if (!at && !form) break; -- } -+ di_skip_die_attributes(&p); - for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) { - if (n == 0) { - fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number); -@@ -1257,12 +1278,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) - } - uleb128(&p); /* tag */ - p++; /* has_children */ -- /* skip content */ -- for (;;) { -- uint64_t at = uleb128(&p); -- uint64_t form = uleb128(&p); -- if (!at && !form) break; -- } -+ di_skip_die_attributes(&p); - } - return p; - } -@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v) - } - } - -+static uint64_t -+read_dw_form_addr(DebugInfoReader *reader, char **ptr) -+{ -+ char *p = *ptr; -+ *ptr = p + reader->format; -+ if (reader->format == 4) { -+ return read_uint32(&p); -+ } else if (reader->format == 8) { -+ return read_uint64(&p); -+ } else { -+ fprintf(stderr,"unknown address_size:%d", reader->address_size); -+ abort(); -+ } -+} -+ - static uintptr_t - ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) - { -@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) - } - else if (ptr->ranges_set) { - /* TODO: support base address selection entry */ -- char *p = reader->obj->debug_ranges.ptr + ptr->ranges; -+ char *p; - uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc; -+ if (reader->obj->debug_rnglists.ptr) { -+ p = reader->obj->debug_rnglists.ptr + ptr->ranges; -+ for (;;) { -+ uint8_t rle = read_uint8(&p); -+ uintptr_t base_address = 0; -+ uintptr_t from, to; -+ if (rle == DW_RLE_end_of_list) break; -+ switch (rle) { -+ case DW_RLE_base_addressx: -+ uleb128(&p); -+ break; -+ case DW_RLE_startx_endx: -+ uleb128(&p); -+ uleb128(&p); -+ break; -+ case DW_RLE_startx_length: -+ uleb128(&p); -+ uleb128(&p); -+ break; -+ case DW_RLE_offset_pair: -+ from = base_address + uleb128(&p); -+ to = base_address + uleb128(&p); -+ if (base + from <= addr && addr < base + to) { -+ return from; -+ } -+ break; -+ case DW_RLE_base_address: -+ base_address = read_dw_form_addr(reader, &p); -+ break; -+ case DW_RLE_start_end: -+ read_dw_form_addr(reader, &p); -+ read_dw_form_addr(reader, &p); -+ break; -+ case DW_RLE_start_length: -+ read_dw_form_addr(reader, &p); -+ uleb128(&p); -+ break; -+ } -+ } -+ return false; -+ } -+ p = reader->obj->debug_ranges.ptr + ptr->ranges; - for (;;) { - uintptr_t from = read_uintptr(&p); - uintptr_t to = read_uintptr(&p); -@@ -1750,6 +1823,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, - ".debug_info", - ".debug_line", - ".debug_ranges", -+ ".debug_rnglists", - ".debug_str" - }; - -@@ -2006,6 +2080,7 @@ found_mach_header: - "__debug_info", - "__debug_line", - "__debug_ranges", -+ "__debug_rnglists", - "__debug_str" - }; - struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd; diff --git a/ruby-3.1.0-Use-EVP-API-in-more-places.patch b/ruby-3.1.0-Use-EVP-API-in-more-places.patch deleted file mode 100644 index f9c4580..0000000 --- a/ruby-3.1.0-Use-EVP-API-in-more-places.patch +++ /dev/null @@ -1,831 +0,0 @@ -From cf070378020088cd7e69b1cb08be68152ab8a078 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 17 May 2020 18:25:38 +0900 -Subject: [PATCH 1/3] pkey: implement #to_text using EVP API - -Use EVP_PKEY_print_private() instead of the low-level API *_print() -functions, such as RSA_print(). - -EVP_PKEY_print_*() family was added in OpenSSL 1.0.0. - -Note that it falls back to EVP_PKEY_print_public() and -EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH -type for which _private() fails if the private component is not set in -the pkey object. - -Since the new API works in the same way for all key types, we now -implement #to_text in the base class OpenSSL::PKey::PKey rather than in -each subclass. ---- - ext/openssl/ossl_pkey.c | 38 +++++++++++++++++++++++++++++++++++++ - ext/openssl/ossl_pkey_dh.c | 29 ---------------------------- - ext/openssl/ossl_pkey_dsa.c | 29 ---------------------------- - ext/openssl/ossl_pkey_ec.c | 27 -------------------------- - ext/openssl/ossl_pkey_rsa.c | 31 ------------------------------ - test/openssl/test_pkey.rb | 5 +++++ - 6 files changed, 43 insertions(+), 116 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index f9282b9417..21cd4b2cda 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -539,6 +539,43 @@ ossl_pkey_inspect(VALUE self) - OBJ_nid2sn(nid)); - } - -+/* -+ * call-seq: -+ * pkey.to_text -> string -+ * -+ * Dumps key parameters, public key, and private key components contained in -+ * the key into a human-readable text. -+ * -+ * This is intended for debugging purpose. -+ * -+ * See also the man page EVP_PKEY_print_private(3). -+ */ -+static VALUE -+ossl_pkey_to_text(VALUE self) -+{ -+ EVP_PKEY *pkey; -+ BIO *bio; -+ -+ GetPKey(self, pkey); -+ if (!(bio = BIO_new(BIO_s_mem()))) -+ ossl_raise(ePKeyError, "BIO_new"); -+ -+ if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1) -+ goto out; -+ OSSL_BIO_reset(bio); -+ if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1) -+ goto out; -+ -+ BIO_free(bio); -+ ossl_raise(ePKeyError, "EVP_PKEY_print_params"); -+ -+ out: -+ return ossl_membio2str(bio); -+} -+ - VALUE - ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) - { -@@ -1039,6 +1076,7 @@ Init_ossl_pkey(void) - rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); - rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); - rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); -+ rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); - rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); - rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); - rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index 6b477b077c..acd3bf474e 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -266,34 +266,6 @@ ossl_dh_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * dh.to_text -> aString -- * -- * Prints all parameters of key to buffer -- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! -- * Don't use :-)) (I's up to you) -- */ --static VALUE --ossl_dh_to_text(VALUE self) --{ -- DH *dh; -- BIO *out; -- VALUE str; -- -- GetDH(self, dh); -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eDHError, NULL); -- } -- if (!DHparams_print(out, dh)) { -- BIO_free(out); -- ossl_raise(eDHError, NULL); -- } -- str = ossl_membio2str(out); -- -- return str; --} -- - /* - * call-seq: - * dh.public_key -> aDH -@@ -426,7 +398,6 @@ Init_ossl_dh(void) - rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); - rb_define_method(cDH, "public?", ossl_dh_is_public, 0); - rb_define_method(cDH, "private?", ossl_dh_is_private, 0); -- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0); - rb_define_method(cDH, "export", ossl_dh_export, 0); - rb_define_alias(cDH, "to_pem", "export"); - rb_define_alias(cDH, "to_s", "export"); -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index 1c5a8a737e..f017cceb4a 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -264,34 +264,6 @@ ossl_dsa_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * dsa.to_text -> aString -- * -- * Prints all parameters of key to buffer -- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! -- * Don't use :-)) (I's up to you) -- */ --static VALUE --ossl_dsa_to_text(VALUE self) --{ -- DSA *dsa; -- BIO *out; -- VALUE str; -- -- GetDSA(self, dsa); -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eDSAError, NULL); -- } -- if (!DSA_print(out, dsa, 0)) { /* offset = 0 */ -- BIO_free(out); -- ossl_raise(eDSAError, NULL); -- } -- str = ossl_membio2str(out); -- -- return str; --} -- - /* - * call-seq: - * dsa.public_key -> aDSA -@@ -469,7 +441,6 @@ Init_ossl_dsa(void) - - rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); - rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); -- rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0); - rb_define_method(cDSA, "export", ossl_dsa_export, -1); - rb_define_alias(cDSA, "to_pem", "export"); - rb_define_alias(cDSA, "to_s", "export"); -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index c2534251c3..ecb8305184 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -417,32 +417,6 @@ ossl_ec_key_to_der(VALUE self) - else - return ossl_pkey_export_spki(self, 1); - } -- --/* -- * call-seq: -- * key.to_text => String -- * -- * See the OpenSSL documentation for EC_KEY_print() -- */ --static VALUE ossl_ec_key_to_text(VALUE self) --{ -- EC_KEY *ec; -- BIO *out; -- VALUE str; -- -- GetEC(self, ec); -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eECError, "BIO_new(BIO_s_mem())"); -- } -- if (!EC_KEY_print(out, ec, 0)) { -- BIO_free(out); -- ossl_raise(eECError, "EC_KEY_print"); -- } -- str = ossl_membio2str(out); -- -- return str; --} -- - /* - * call-seq: - * key.generate_key! => self -@@ -1633,7 +1607,6 @@ void Init_ossl_ec(void) - rb_define_method(cEC, "export", ossl_ec_key_export, -1); - rb_define_alias(cEC, "to_pem", "export"); - rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); -- rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0); - - - rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc); -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 43f82cb29e..7a7e66dbda 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -587,36 +587,6 @@ ossl_rsa_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * rsa.to_text => String -- * -- * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! -- * -- * Dumps all parameters of a keypair to a String -- * -- * Don't use :-)) (It's up to you) -- */ --static VALUE --ossl_rsa_to_text(VALUE self) --{ -- RSA *rsa; -- BIO *out; -- VALUE str; -- -- GetRSA(self, rsa); -- if (!(out = BIO_new(BIO_s_mem()))) { -- ossl_raise(eRSAError, NULL); -- } -- if (!RSA_print(out, rsa, 0)) { /* offset = 0 */ -- BIO_free(out); -- ossl_raise(eRSAError, NULL); -- } -- str = ossl_membio2str(out); -- -- return str; --} -- - /* - * call-seq: - * rsa.public_key -> RSA -@@ -738,7 +708,6 @@ Init_ossl_rsa(void) - - rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); - rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); -- rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0); - rb_define_method(cRSA, "export", ossl_rsa_export, -1); - rb_define_alias(cRSA, "to_pem", "export"); - rb_define_alias(cRSA, "to_s", "export"); -diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb -index 5307fe5b08..3630458b3c 100644 ---- a/test/openssl/test_pkey.rb -+++ b/test/openssl/test_pkey.rb -@@ -151,4 +151,9 @@ def test_x25519 - assert_equal bob_pem, bob.public_to_pem - assert_equal [shared_secret].pack("H*"), alice.derive(bob) - end -+ -+ def test_to_text -+ rsa = Fixtures.pkey("rsa1024") -+ assert_include rsa.to_text, "publicExponent" -+ end - end --- -2.32.0 - - -From 0c45b22e485bfa62f4d704b08e3704e6444118c4 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 15 Apr 2021 19:11:32 +0900 -Subject: [PATCH 2/3] pkey: implement {DH,DSA,RSA}#public_key in Ruby - -The low-level API that is used to implement #public_key is deprecated -in OpenSSL 3.0. It is actually very simple to implement in another way, -using existing methods only, in much shorter code. Let's do it. - -While we are at it, the documentation is updated to recommend against -using #public_key. Now that OpenSSL::PKey::PKey implements public_to_der -method, there is no real use case for #public_key in newly written Ruby -programs. ---- - ext/openssl/lib/openssl/pkey.rb | 55 ++++++++++++++++++++++++++++ - ext/openssl/ossl_pkey_dh.c | 63 +++++++-------------------------- - ext/openssl/ossl_pkey_dsa.c | 42 ---------------------- - ext/openssl/ossl_pkey_rsa.c | 58 +----------------------------- - test/openssl/test_pkey_rsa.rb | 37 ++++++++++--------- - 5 files changed, 87 insertions(+), 168 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 53ee52f98b..569559e1ce 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -10,6 +10,30 @@ module OpenSSL::PKey - class DH - include OpenSSL::Marshal - -+ # :call-seq: -+ # dh.public_key -> dhnew -+ # -+ # Returns a new DH instance that carries just the \DH parameters. -+ # -+ # Contrary to the method name, the returned DH object contains only -+ # parameters and not the public key. -+ # -+ # This method is provided for backwards compatibility. In most cases, there -+ # is no need to call this method. -+ # -+ # For the purpose of re-generating the key pair while keeping the -+ # parameters, check OpenSSL::PKey.generate_key. -+ # -+ # Example: -+ # # OpenSSL::PKey::DH.generate by default generates a random key pair -+ # dh1 = OpenSSL::PKey::DH.generate(2048) -+ # p dh1.priv_key #=> # -+ # dhcopy = dh1.public_key -+ # p dhcopy.priv_key #=> nil -+ def public_key -+ DH.new(to_der) -+ end -+ - # :call-seq: - # dh.compute_key(pub_bn) -> string - # -@@ -89,6 +113,22 @@ def new(*args, &blk) # :nodoc: - class DSA - include OpenSSL::Marshal - -+ # :call-seq: -+ # dsa.public_key -> dsanew -+ # -+ # Returns a new DSA instance that carries just the \DSA parameters and the -+ # public key. -+ # -+ # This method is provided for backwards compatibility. In most cases, there -+ # is no need to call this method. -+ # -+ # For the purpose of serializing the public key, to PEM or DER encoding of -+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and -+ # PKey#public_to_der. -+ def public_key -+ OpenSSL::PKey.read(public_to_der) -+ end -+ - class << self - # :call-seq: - # DSA.generate(size) -> dsa -@@ -159,6 +199,21 @@ def to_bn(conversion_form = group.point_conversion_form) - class RSA - include OpenSSL::Marshal - -+ # :call-seq: -+ # rsa.public_key -> rsanew -+ # -+ # Returns a new RSA instance that carries just the public key components. -+ # -+ # This method is provided for backwards compatibility. In most cases, there -+ # is no need to call this method. -+ # -+ # For the purpose of serializing the public key, to PEM or DER encoding of -+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and -+ # PKey#public_to_der. -+ def public_key -+ OpenSSL::PKey.read(public_to_der) -+ end -+ - class << self - # :call-seq: - # RSA.generate(size, exponent = 65537) -> RSA -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index acd3bf474e..a512b209d3 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -266,48 +266,6 @@ ossl_dh_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * dh.public_key -> aDH -- * -- * Returns a new DH instance that carries just the public information, i.e. -- * the prime _p_ and the generator _g_, but no public/private key yet. Such -- * a pair may be generated using DH#generate_key!. The "public key" needed -- * for a key exchange with DH#compute_key is considered as per-session -- * information and may be retrieved with DH#pub_key once a key pair has -- * been generated. -- * If the current instance already contains private information (and thus a -- * valid public/private key pair), this information will no longer be present -- * in the new instance generated by DH#public_key. This feature is helpful for -- * publishing the Diffie-Hellman parameters without leaking any of the private -- * per-session information. -- * -- * === Example -- * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set -- * public_key = dh.public_key # contains only prime and generator -- * parameters = public_key.to_der # it's safe to publish this -- */ --static VALUE --ossl_dh_to_public_key(VALUE self) --{ -- EVP_PKEY *pkey; -- DH *orig_dh, *dh; -- VALUE obj; -- -- obj = rb_obj_alloc(rb_obj_class(self)); -- GetPKey(obj, pkey); -- -- GetDH(self, orig_dh); -- dh = DHparams_dup(orig_dh); -- if (!dh) -- ossl_raise(eDHError, "DHparams_dup"); -- if (!EVP_PKEY_assign_DH(pkey, dh)) { -- DH_free(dh); -- ossl_raise(eDHError, "EVP_PKEY_assign_DH"); -- } -- return obj; --} -- - /* - * call-seq: - * dh.params_ok? -> true | false -@@ -384,14 +342,20 @@ Init_ossl_dh(void) - * The per-session private key, an OpenSSL::BN. - * - * === Example of a key exchange -- * dh1 = OpenSSL::PKey::DH.new(2048) -- * der = dh1.public_key.to_der #you may send this publicly to the participating party -- * dh2 = OpenSSL::PKey::DH.new(der) -- * dh2.generate_key! #generate the per-session key pair -- * symm_key1 = dh1.compute_key(dh2.pub_key) -- * symm_key2 = dh2.compute_key(dh1.pub_key) -+ * # you may send the parameters (der) and own public key (pub1) publicly -+ * # to the participating party -+ * dh1 = OpenSSL::PKey::DH.new(2048) -+ * der = dh1.to_der -+ * pub1 = dh1.pub_key -+ * -+ * # the other party generates its per-session key pair -+ * dhparams = OpenSSL::PKey::DH.new(der) -+ * dh2 = OpenSSL::PKey.generate_key(dhparams) -+ * pub2 = dh2.pub_key - * -- * puts symm_key1 == symm_key2 # => true -+ * symm_key1 = dh1.compute_key(pub2) -+ * symm_key2 = dh2.compute_key(pub1) -+ * puts symm_key1 == symm_key2 # => true - */ - cDH = rb_define_class_under(mPKey, "DH", cPKey); - rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); -@@ -402,7 +366,6 @@ Init_ossl_dh(void) - rb_define_alias(cDH, "to_pem", "export"); - rb_define_alias(cDH, "to_s", "export"); - 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); - - DEF_OSSL_PKEY_BN(cDH, dh, p); -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index f017cceb4a..ab9ac781e8 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -264,47 +264,6 @@ ossl_dsa_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * dsa.public_key -> aDSA -- * -- * Returns a new DSA instance that carries just the public key information. -- * If the current instance has also private key information, this will no -- * longer be present in the new instance. This feature is helpful for -- * publishing the public key information without leaking any of the private -- * information. -- * -- * === Example -- * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information -- * pub_key = dsa.public_key # has only the public part available -- * pub_key_der = pub_key.to_der # it's safe to publish this -- * -- * -- */ --static VALUE --ossl_dsa_to_public_key(VALUE self) --{ -- EVP_PKEY *pkey, *pkey_new; -- DSA *dsa; -- VALUE obj; -- -- GetPKeyDSA(self, pkey); -- obj = rb_obj_alloc(rb_obj_class(self)); -- GetPKey(obj, pkey_new); -- --#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \ -- (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa)) -- dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey)); --#undef DSAPublicKey_dup -- if (!dsa) -- ossl_raise(eDSAError, "DSAPublicKey_dup"); -- if (!EVP_PKEY_assign_DSA(pkey_new, dsa)) { -- DSA_free(dsa); -- ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); -- } -- return obj; --} -- - /* - * call-seq: - * dsa.syssign(string) -> aString -@@ -445,7 +404,6 @@ Init_ossl_dsa(void) - rb_define_alias(cDSA, "to_pem", "export"); - rb_define_alias(cDSA, "to_s", "export"); - rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); -- rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); - rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); - rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); - -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 7a7e66dbda..1c5476cdcd 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -390,7 +390,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) - * data = "Sign me!" - * pkey = OpenSSL::PKey::RSA.new(2048) - * signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256") -- * pub_key = pkey.public_key -+ * pub_key = OpenSSL::PKey.read(pkey.public_to_der) - * puts pub_key.verify_pss("SHA256", signature, data, - * salt_length: :auto, mgf1_hash: "SHA256") # => true - */ -@@ -587,61 +587,6 @@ ossl_rsa_get_params(VALUE self) - return hash; - } - --/* -- * call-seq: -- * rsa.public_key -> RSA -- * -- * Makes new RSA instance containing the public key from the private key. -- */ --static VALUE --ossl_rsa_to_public_key(VALUE self) --{ -- EVP_PKEY *pkey, *pkey_new; -- RSA *rsa; -- VALUE obj; -- -- GetPKeyRSA(self, pkey); -- obj = rb_obj_alloc(rb_obj_class(self)); -- GetPKey(obj, pkey_new); -- -- rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey)); -- if (!rsa) -- ossl_raise(eRSAError, "RSAPublicKey_dup"); -- if (!EVP_PKEY_assign_RSA(pkey_new, rsa)) { -- RSA_free(rsa); -- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); -- } -- return obj; --} -- --/* -- * TODO: Test me -- --static VALUE --ossl_rsa_blinding_on(VALUE self) --{ -- RSA *rsa; -- -- GetRSA(self, rsa); -- -- if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) { -- ossl_raise(eRSAError, NULL); -- } -- return self; --} -- --static VALUE --ossl_rsa_blinding_off(VALUE self) --{ -- RSA *rsa; -- -- GetRSA(self, rsa); -- RSA_blinding_off(rsa); -- -- return self; --} -- */ -- - /* - * Document-method: OpenSSL::PKey::RSA#set_key - * call-seq: -@@ -712,7 +657,6 @@ Init_ossl_rsa(void) - rb_define_alias(cRSA, "to_pem", "export"); - rb_define_alias(cRSA, "to_s", "export"); - rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); -- rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); - rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); - rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); - rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index d1e68dbc9f..5f8d04e754 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -69,29 +69,28 @@ def test_private - end - - def test_new -- key = OpenSSL::PKey::RSA.new 512 -- pem = key.public_key.to_pem -- OpenSSL::PKey::RSA.new pem -- assert_equal([], OpenSSL.errors) -- end -+ key = OpenSSL::PKey::RSA.new(512) -+ assert_equal 512, key.n.num_bits -+ assert_equal 65537, key.e -+ assert_not_nil key.d - -- def test_new_exponent_default -- assert_equal(65537, OpenSSL::PKey::RSA.new(512).e) -+ # Specify public exponent -+ key2 = OpenSSL::PKey::RSA.new(512, 3) -+ assert_equal 512, key2.n.num_bits -+ assert_equal 3, key2.e -+ assert_not_nil key2.d - end - -- def test_new_with_exponent -- 1.upto(30) do |idx| -- e = (2 ** idx) + 1 -- key = OpenSSL::PKey::RSA.new(512, e) -- assert_equal(e, key.e) -- end -- end -+ def test_s_generate -+ key1 = OpenSSL::PKey::RSA.generate(512) -+ assert_equal 512, key1.n.num_bits -+ assert_equal 65537, key1.e - -- def test_generate -- key = OpenSSL::PKey::RSA.generate(512, 17) -- assert_equal 512, key.n.num_bits -- assert_equal 17, key.e -- assert_not_nil key.d -+ # Specify public exponent -+ key2 = OpenSSL::PKey::RSA.generate(512, 3) -+ assert_equal 512, key2.n.num_bits -+ assert_equal 3, key2.e -+ assert_not_nil key2.d - end - - def test_new_break --- -2.32.0 - - -From 2150af0e55b2a25c24f62006e27e0aec3dc81b57 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 10 Jul 2020 14:34:51 +0900 -Subject: [PATCH 3/3] pkey/dh, pkey/ec: use EVP_PKEY_check() family - -Use EVP_PKEY_param_check() instead of DH_check() if available. Also, -use EVP_PKEY_public_check() instead of EC_KEY_check_key(). - -EVP_PKEY_*check() is part of the EVP API and is meant to replace those -low-level functions. They were added by OpenSSL 1.1.1. It is currently -not provided by LibreSSL. ---- - ext/openssl/extconf.rb | 3 +++ - ext/openssl/ossl_pkey_dh.c | 27 +++++++++++++++++++++++---- - ext/openssl/ossl_pkey_ec.c | 23 +++++++++++++++++++---- - test/openssl/test_pkey_dh.rb | 16 ++++++++++++++++ - 4 files changed, 61 insertions(+), 8 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index b3c6647faf..17d93443fc 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -172,6 +172,9 @@ def find_openssl_library - have_func("EVP_PBE_scrypt") - have_func("SSL_CTX_set_post_handshake_auth") - -+# added in 1.1.1 -+have_func("EVP_PKEY_check") -+ - Logging::message "=== Checking done. ===\n" - - create_header -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index a512b209d3..ca782bbe59 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -273,19 +273,38 @@ ossl_dh_get_params(VALUE self) - * Validates the Diffie-Hellman parameters associated with this instance. - * It checks whether a safe prime and a suitable generator are used. If this - * is not the case, +false+ is returned. -+ * -+ * See also the man page EVP_PKEY_param_check(3). - */ - static VALUE - ossl_dh_check_params(VALUE self) - { -+ int ret; -+#ifdef HAVE_EVP_PKEY_CHECK -+ EVP_PKEY *pkey; -+ EVP_PKEY_CTX *pctx; -+ -+ GetPKey(self, pkey); -+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!pctx) -+ ossl_raise(eDHError, "EVP_PKEY_CTX_new"); -+ ret = EVP_PKEY_param_check(pctx); -+ EVP_PKEY_CTX_free(pctx); -+#else - DH *dh; - int codes; - - GetDH(self, dh); -- if (!DH_check(dh, &codes)) { -- return Qfalse; -- } -+ ret = DH_check(dh, &codes) == 1 && codes == 0; -+#endif - -- return codes == 0 ? Qtrue : Qfalse; -+ if (ret == 1) -+ return Qtrue; -+ else { -+ /* DH_check_ex() will put error entry on failure */ -+ ossl_clear_error(); -+ return Qfalse; -+ } - } - - /* -diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c -index ecb8305184..829529d4b9 100644 ---- a/ext/openssl/ossl_pkey_ec.c -+++ b/ext/openssl/ossl_pkey_ec.c -@@ -443,20 +443,35 @@ static VALUE ossl_ec_key_generate_key(VALUE self) - } - - /* -- * call-seq: -- * key.check_key => true -+ * call-seq: -+ * key.check_key => true - * -- * Raises an exception if the key is invalid. -+ * Raises an exception if the key is invalid. - * -- * See the OpenSSL documentation for EC_KEY_check_key() -+ * See also the man page EVP_PKEY_public_check(3). - */ - static VALUE ossl_ec_key_check_key(VALUE self) - { -+#ifdef HAVE_EVP_PKEY_CHECK -+ EVP_PKEY *pkey; -+ EVP_PKEY_CTX *pctx; -+ int ret; -+ -+ GetPKey(self, pkey); -+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); -+ if (!pctx) -+ ossl_raise(eDHError, "EVP_PKEY_CTX_new"); -+ ret = EVP_PKEY_public_check(pctx); -+ EVP_PKEY_CTX_free(pctx); -+ if (ret != 1) -+ ossl_raise(eECError, "EVP_PKEY_public_check"); -+#else - EC_KEY *ec; - - GetEC(self, ec); - if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_check_key"); -+#endif - - return Qtrue; - } -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index 279ce1984c..f80af8f841 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -86,6 +86,22 @@ def test_key_exchange - assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key)) - end - -+ def test_params_ok? -+ dh0 = Fixtures.pkey("dh1024") -+ -+ dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([ -+ OpenSSL::ASN1::Integer(dh0.p), -+ OpenSSL::ASN1::Integer(dh0.g) -+ ])) -+ assert_equal(true, dh1.params_ok?) -+ -+ dh2 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([ -+ OpenSSL::ASN1::Integer(dh0.p + 1), -+ OpenSSL::ASN1::Integer(dh0.g) -+ ])) -+ assert_equal(false, dh2.params_ok?) -+ end -+ - def test_dup - dh = Fixtures.pkey("dh1024") - dh2 = dh.dup --- -2.32.0 - diff --git a/ruby-3.1.0-Use-OSSL_DECODER-to-load-encrypted-PEM-on-OpenSSL-3.0.patch b/ruby-3.1.0-Use-OSSL_DECODER-to-load-encrypted-PEM-on-OpenSSL-3.0.patch deleted file mode 100644 index dfdd690..0000000 --- a/ruby-3.1.0-Use-OSSL_DECODER-to-load-encrypted-PEM-on-OpenSSL-3.0.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 8c185e0ae5e42bf5f3d76a1a0898946671116fa3 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 3 Nov 2021 23:31:29 +0900 -Subject: [PATCH 1/2] pkey: test parsing concatenated PEM string - -PEM-encoded private keys are sometimes stored together with irrelevant -PEM blocks, such as the corresponding X.509 certificate. - -PEM_read_bio_*() family automatically skips unknown PEM blocks, but on -OpenSSL 3.0 we will be using the new OSSL_DECODER API instead due to -some breaking changes around the password callback. - -Let's add a test case so that we won't break the current behavior. ---- - test/openssl/test_pkey_rsa.rb | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index dbe87ba4..7510658d 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -306,6 +306,12 @@ def test_RSAPrivateKey - - assert_equal asn1.to_der, rsa1024.to_der - assert_equal pem, rsa1024.export -+ -+ # Unknown PEM prepended -+ cert = issue_cert(OpenSSL::X509::Name.new([["CN", "nobody"]]), rsa1024, 1, [], nil, nil) -+ str = cert.to_text + cert.to_pem + rsa1024.to_pem -+ key = OpenSSL::PKey::RSA.new(str) -+ assert_same_rsa rsa1024, key - end - - def test_RSAPrivateKey_encrypted - -From a84ea531bbd080c3f58fe8d3dc9ffb1af2251f35 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sat, 20 Mar 2021 23:16:16 +0900 -Subject: [PATCH 2/2] pkey: use OSSL_DECODER to load encrypted PEM on OpenSSL - 3.0 - -OpenSSL 3.0 has rewritten routines to load pkeys (PEM_read_bio_* and -d2i_* functions) around the newly introduced OSSL_DECODER API. - -This comes with a slight behavior change. They now decrypt and parse -each encountered PEM block, then check the kind of the block. This used -to be the reverse: they checked the PEM header to see the kind, and then -decrypted the content. This means that the password callback may now be -called repeatedly. - -Let's use the OSSL_DECODER API directly on OpenSSL 3.0 so that the -return value from the password callback will be reused automatically. ---- - ext/openssl/ossl_pkey.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index f9f5162e..b08168a5 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -78,6 +78,45 @@ ossl_pkey_new(EVP_PKEY *pkey) - return obj; - } - -+#if OSSL_OPENSSL_PREREQ(3, 0, 0) -+# include -+ -+EVP_PKEY * -+ossl_pkey_read_generic(BIO *bio, VALUE pass) -+{ -+ void *ppass = (void *)pass; -+ OSSL_DECODER_CTX *dctx; -+ EVP_PKEY *pkey = NULL; -+ int pos = 0, pos2; -+ -+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL); -+ if (!dctx) -+ goto out; -+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1) -+ goto out; -+ -+ /* First check DER */ -+ if (OSSL_DECODER_from_bio(dctx, bio) == 1) -+ goto out; -+ -+ /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */ -+ OSSL_BIO_reset(bio); -+ if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1) -+ goto out; -+ while (OSSL_DECODER_from_bio(dctx, bio) != 1) { -+ if (BIO_eof(bio)) -+ goto out; -+ pos2 = BIO_tell(bio); -+ if (pos2 < 0 || pos2 <= pos) -+ goto out; -+ pos = pos2; -+ } -+ -+ out: -+ OSSL_DECODER_CTX_free(dctx); -+ return pkey; -+} -+#else - EVP_PKEY * - ossl_pkey_read_generic(BIO *bio, VALUE pass) - { -@@ -106,6 +145,7 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass) - out: - return pkey; - } -+#endif - - /* - * call-seq: diff --git a/ruby-3.1.0-Use-high-level-EVP-interface-to-generate-parameters-and-keys.patch b/ruby-3.1.0-Use-high-level-EVP-interface-to-generate-parameters-and-keys.patch deleted file mode 100644 index d02ce45..0000000 --- a/ruby-3.1.0-Use-high-level-EVP-interface-to-generate-parameters-and-keys.patch +++ /dev/null @@ -1,1113 +0,0 @@ -From e8504c6248c4b0e5e961f57f004e1133c20c88a5 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 5 Apr 2021 00:30:01 +0900 -Subject: [PATCH 1/5] pkey: fix interrupt handling in - OpenSSL::PKey.generate_key - -rb_thread_call_without_gvl() can be interrupted, but it may be able to -resume the operation. Call rb_thread_check_ints() to see if it raises -an exception or not. ---- - ext/openssl/ossl_pkey.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 22e9f19982..d76f0600d1 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -239,7 +239,7 @@ struct pkey_blocking_generate_arg { - int state; - int yield: 1; - int genparam: 1; -- int stop: 1; -+ int interrupted: 1; - }; - - static VALUE -@@ -261,23 +261,31 @@ static int - pkey_gen_cb(EVP_PKEY_CTX *ctx) - { - struct pkey_blocking_generate_arg *arg = EVP_PKEY_CTX_get_app_data(ctx); -+ int state; - - if (arg->yield) { -- int state; - rb_protect(pkey_gen_cb_yield, (VALUE)ctx, &state); - if (state) { -- arg->stop = 1; - arg->state = state; -+ return 0; -+ } -+ } -+ if (arg->interrupted) { -+ arg->interrupted = 0; -+ state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL); -+ if (state) { -+ arg->state = state; -+ return 0; - } - } -- return !arg->stop; -+ return 1; - } - - static void - pkey_blocking_gen_stop(void *ptr) - { - struct pkey_blocking_generate_arg *arg = ptr; -- arg->stop = 1; -+ arg->interrupted = 1; - } - - static void * --- -2.32.0 - - -From f433d1b680e7ac5ef13fc15b0844267222438cf3 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 17 May 2020 20:48:23 +0900 -Subject: [PATCH 2/5] 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. ---- - ext/openssl/lib/openssl/pkey.rb | 57 ++++++++++ - ext/openssl/ossl_pkey_dh.c | 186 ++++++-------------------------- - test/openssl/test_pkey_dh.rb | 15 ++- - 3 files changed, 101 insertions(+), 157 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 @@ def compute_key(pub_bn) - 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 -diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c -index 5bc1c49ca1..6b477b077c 100644 ---- a/ext/openssl/ossl_pkey_dh.c -+++ b/ext/openssl/ossl_pkey_dh.c -@@ -32,147 +32,56 @@ VALUE eDHError; - /* - * Private - */ --struct dh_blocking_gen_arg { -- DH *dh; -- int size; -- int gen; -- BN_GENCB *cb; -- int result; --}; -- --static void * --dh_blocking_gen(void *arg) --{ -- struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg; -- gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb); -- return 0; --} -- --static DH * --dh_generate(int size, int gen) --{ -- struct ossl_generate_cb_arg cb_arg = { 0 }; -- struct dh_blocking_gen_arg gen_arg; -- DH *dh = DH_new(); -- BN_GENCB *cb = BN_GENCB_new(); -- -- if (!dh || !cb) { -- DH_free(dh); -- BN_GENCB_free(cb); -- ossl_raise(eDHError, "malloc failure"); -- } -- -- if (rb_block_given_p()) -- cb_arg.yield = 1; -- BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); -- gen_arg.dh = dh; -- gen_arg.size = size; -- gen_arg.gen = gen; -- gen_arg.cb = cb; -- if (cb_arg.yield == 1) { -- /* we cannot release GVL when callback proc is supplied */ -- dh_blocking_gen(&gen_arg); -- } else { -- /* there's a chance to unblock */ -- rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); -- } -- -- BN_GENCB_free(cb); -- if (!gen_arg.result) { -- DH_free(dh); -- if (cb_arg.state) { -- /* Clear OpenSSL error queue before re-raising. */ -- ossl_clear_error(); -- rb_jump_tag(cb_arg.state); -- } -- ossl_raise(eDHError, "DH_generate_parameters_ex"); -- } -- -- if (!DH_generate_key(dh)) { -- DH_free(dh); -- ossl_raise(eDHError, "DH_generate_key"); -- } -- -- return dh; --} -- --/* -- * call-seq: -- * DH.generate(size [, generator]) -> dh -- * -- * Creates a new DH instance from scratch by generating the private and public -- * components alike. -- * -- * === Parameters -- * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. -- * * _generator_ is a small number > 1, typically 2 or 5. -- * -- */ --static VALUE --ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) --{ -- EVP_PKEY *pkey; -- DH *dh ; -- int g = 2; -- VALUE size, gen, obj; -- -- if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { -- g = NUM2INT(gen); -- } -- obj = rb_obj_alloc(klass); -- GetPKey(obj, pkey); -- -- dh = dh_generate(NUM2INT(size), g); -- if (!EVP_PKEY_assign_DH(pkey, dh)) { -- DH_free(dh); -- ossl_raise(eDHError, "EVP_PKEY_assign_DH"); -- } -- return obj; --} -- - /* - * call-seq: - * DH.new -> dh - * DH.new(string) -> dh - * DH.new(size [, generator]) -> dh - * -- * Either generates a DH instance from scratch or by reading already existing -- * DH parameters from _string_. Note that when reading a DH instance from -- * data that was encoded from a DH instance by using DH#to_pem or DH#to_der -- * the result will *not* contain a public/private key pair yet. This needs to -- * be generated using DH#generate_key! first. -+ * Creates a new instance of OpenSSL::PKey::DH. -+ * -+ * If called without arguments, an empty instance without any parameter or key -+ * components is created. Use #set_pqg to manually set the parameters afterwards -+ * (and optionally #set_key to set private and public key components). -+ * -+ * If a String is given, tries to parse it as a DER- or PEM- encoded parameters. -+ * See also OpenSSL::PKey.read which can parse keys of any kinds. -+ * -+ * The DH.new(size [, generator]) form is an alias of DH.generate. - * -- * === Parameters -- * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. -- * * _generator_ is a small number > 1, typically 2 or 5. -- * * _string_ contains the DER or PEM encoded key. -+ * +string+:: -+ * A String that contains the DER or PEM encoded key. -+ * +size+:: -+ * See DH.generate. -+ * +generator+:: -+ * See DH.generate. - * -- * === Examples -- * DH.new # -> dh -- * DH.new(1024) # -> dh -- * DH.new(1024, 5) # -> dh -- * #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 -+ * Examples: -+ * # Creating an instance from scratch -+ * dh = 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) -+ * -+ * # 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 - */ - static VALUE - ossl_dh_initialize(int argc, VALUE *argv, VALUE self) - { - EVP_PKEY *pkey; - DH *dh; -- int g = 2; - BIO *in; -- VALUE arg, gen; -+ VALUE arg; - - GetPKey(self, pkey); -- if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) { -- dh = DH_new(); -- } -- else if (RB_INTEGER_TYPE_P(arg)) { -- if (!NIL_P(gen)) { -- g = NUM2INT(gen); -- } -- dh = dh_generate(NUM2INT(arg), g); -+ /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ -+ if (rb_scan_args(argc, argv, "01", &arg) == 0) { -+ dh = DH_new(); -+ if (!dh) -+ ossl_raise(eDHError, "DH_new"); - } - else { - arg = ossl_to_der_if_possible(arg); -@@ -449,33 +358,6 @@ ossl_dh_check_params(VALUE self) - return codes == 0 ? Qtrue : Qfalse; - } - --/* -- * 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. -- * -- * === 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 -- */ --static VALUE --ossl_dh_generate_key(VALUE self) --{ -- DH *dh; -- -- GetDH(self, dh); -- if (!DH_generate_key(dh)) -- ossl_raise(eDHError, "Failed to generate key"); -- return self; --} -- - /* - * Document-method: OpenSSL::PKey::DH#set_pqg - * call-seq: -@@ -540,7 +422,6 @@ Init_ossl_dh(void) - * puts symm_key1 == symm_key2 # => true - */ - cDH = rb_define_class_under(mPKey, "DH", cPKey); -- rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1); - rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); - rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); - rb_define_method(cDH, "public?", ossl_dh_is_public, 0); -@@ -552,7 +433,6 @@ 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); - - DEF_OSSL_PKEY_BN(cDH, dh, p); - DEF_OSSL_PKEY_BN(cDH, dh, q); -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index 9efc3ba68d..279ce1984c 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -4,12 +4,19 @@ - if defined?(OpenSSL) && defined?(OpenSSL::PKey::DH) - - class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase -- NEW_KEYLEN = 256 -+ NEW_KEYLEN = 2048 - -- def test_new -+ def test_new_empty -+ dh = OpenSSL::PKey::DH.new -+ assert_equal nil, dh.p -+ assert_equal nil, dh.priv_key -+ end -+ -+ def test_new_generate -+ # This test is slow - dh = OpenSSL::PKey::DH.new(NEW_KEYLEN) - assert_key(dh) -- end -+ end if ENV["OSSL_TEST_ALL"] - - def test_new_break - assert_nil(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break }) -@@ -80,7 +87,7 @@ def test_key_exchange - end - - def test_dup -- dh = OpenSSL::PKey::DH.new(NEW_KEYLEN) -+ dh = Fixtures.pkey("dh1024") - dh2 = dh.dup - assert_equal dh.to_der, dh2.to_der # params - assert_equal_params dh, dh2 # keys --- -2.32.0 - - -From ba1d1d68ac2b489691eb3fe2052e77b3e57a372b Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 17 May 2020 20:48:23 +0900 -Subject: [PATCH 3/5] pkey/rsa: use high level EVP interface to generate - parameters and keys - -Implement PKey::RSA.new(size, exponent) and PKey::RSA.generate using -OpenSSL::PKey.generate_key instead of the low level RSA functions. ---- - ext/openssl/lib/openssl/pkey.rb | 30 ++++++++ - ext/openssl/ossl_pkey_rsa.c | 132 ++++---------------------------- - 2 files changed, 46 insertions(+), 116 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 5a3d0ed1ef..3bef06e3b3 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -128,5 +128,35 @@ def to_bn(conversion_form = group.point_conversion_form) - - class RSA - include OpenSSL::Marshal -+ -+ class << self -+ # :call-seq: -+ # RSA.generate(size, exponent = 65537) -> RSA -+ # -+ # Generates an \RSA keypair. -+ # -+ # See also OpenSSL::PKey.generate_key. -+ # -+ # +size+:: -+ # The desired key size in bits. -+ # +exponent+:: -+ # An odd Integer, normally 3, 17, or 65537. -+ def generate(size, exp = 0x10001, &blk) -+ OpenSSL::PKey.generate_key("RSA", { -+ "rsa_keygen_bits" => size, -+ "rsa_keygen_pubexp" => exp, -+ }, &blk) -+ end -+ -+ # Handle RSA.new(size, exponent) 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 - end -diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c -index 3c298a2aea..43f82cb29e 100644 ---- a/ext/openssl/ossl_pkey_rsa.c -+++ b/ext/openssl/ossl_pkey_rsa.c -@@ -47,125 +47,28 @@ VALUE eRSAError; - /* - * Private - */ --struct rsa_blocking_gen_arg { -- RSA *rsa; -- BIGNUM *e; -- int size; -- BN_GENCB *cb; -- int result; --}; -- --static void * --rsa_blocking_gen(void *arg) --{ -- struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg; -- gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb); -- return 0; --} -- --static RSA * --rsa_generate(int size, unsigned long exp) --{ -- int i; -- struct ossl_generate_cb_arg cb_arg = { 0 }; -- struct rsa_blocking_gen_arg gen_arg; -- RSA *rsa = RSA_new(); -- BIGNUM *e = BN_new(); -- BN_GENCB *cb = BN_GENCB_new(); -- -- if (!rsa || !e || !cb) { -- RSA_free(rsa); -- BN_free(e); -- BN_GENCB_free(cb); -- ossl_raise(eRSAError, "malloc failure"); -- } -- for (i = 0; i < (int)sizeof(exp) * 8; ++i) { -- if (exp & (1UL << i)) { -- if (BN_set_bit(e, i) == 0) { -- BN_free(e); -- RSA_free(rsa); -- BN_GENCB_free(cb); -- ossl_raise(eRSAError, "BN_set_bit"); -- } -- } -- } -- -- if (rb_block_given_p()) -- cb_arg.yield = 1; -- BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); -- gen_arg.rsa = rsa; -- gen_arg.e = e; -- gen_arg.size = size; -- gen_arg.cb = cb; -- if (cb_arg.yield == 1) { -- /* we cannot release GVL when callback proc is supplied */ -- rsa_blocking_gen(&gen_arg); -- } else { -- /* there's a chance to unblock */ -- rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); -- } -- -- BN_GENCB_free(cb); -- BN_free(e); -- if (!gen_arg.result) { -- RSA_free(rsa); -- if (cb_arg.state) { -- /* must clear OpenSSL error stack */ -- ossl_clear_error(); -- rb_jump_tag(cb_arg.state); -- } -- ossl_raise(eRSAError, "RSA_generate_key_ex"); -- } -- -- return rsa; --} -- - /* - * call-seq: -- * RSA.generate(size) => RSA instance -- * RSA.generate(size, exponent) => RSA instance -+ * RSA.new -> rsa -+ * RSA.new(encoded_key [, passphrase]) -> rsa -+ * RSA.new(encoded_key) { passphrase } -> rsa -+ * RSA.new(size [, exponent]) -> rsa - * -- * Generates an RSA keypair. _size_ is an integer representing the desired key -- * size. Keys smaller than 1024 should be considered insecure. _exponent_ is -- * an odd number normally 3, 17, or 65537. -- */ --static VALUE --ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) --{ --/* why does this method exist? why can't initialize take an optional exponent? */ -- EVP_PKEY *pkey; -- RSA *rsa; -- VALUE size, exp; -- VALUE obj; -- -- rb_scan_args(argc, argv, "11", &size, &exp); -- obj = rb_obj_alloc(klass); -- GetPKey(obj, pkey); -- -- rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); -- if (!EVP_PKEY_assign_RSA(pkey, rsa)) { -- RSA_free(rsa); -- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); -- } -- return obj; --} -- --/* -- * call-seq: -- * RSA.new(size [, exponent]) => RSA instance -- * RSA.new(encoded_key) => RSA instance -- * RSA.new(encoded_key, pass_phrase) => RSA instance -+ * Generates or loads an \RSA keypair. - * -- * Generates or loads an RSA keypair. If an integer _key_size_ is given it -- * represents the desired key size. Keys less than 1024 bits should be -- * considered insecure. -+ * If called without arguments, creates a new instance with no key components -+ * set. They can be set individually by #set_key, #set_factors, and -+ * #set_crt_params. - * -- * A key can instead be loaded from an _encoded_key_ which must be PEM or DER -- * encoded. A _pass_phrase_ can be used to decrypt the key. If none is given -- * OpenSSL will prompt for the pass phrase. -+ * If called with a String, tries to parse as DER or PEM encoding of an \RSA key. -+ * Note that, if _passphrase_ is not specified but the key is encrypted with a -+ * passphrase, \OpenSSL will prompt for it. -+ * See also OpenSSL::PKey.read which can parse keys of any kinds. - * -- * = Examples -+ * If called with a number, generates a new key pair. This form works as an -+ * alias of RSA.generate. - * -+ * Examples: - * OpenSSL::PKey::RSA.new 2048 - * OpenSSL::PKey::RSA.new File.read 'rsa.pem' - * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase' -@@ -179,15 +82,13 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) - VALUE arg, pass; - - GetPKey(self, pkey); -+ /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); - if (argc == 0) { - rsa = RSA_new(); - if (!rsa) - ossl_raise(eRSAError, "RSA_new"); - } -- else if (RB_INTEGER_TYPE_P(arg)) { -- rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass)); -- } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); -@@ -832,7 +733,6 @@ Init_ossl_rsa(void) - */ - cRSA = rb_define_class_under(mPKey, "RSA", cPKey); - -- rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1); - rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); - rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1); - --- -2.32.0 - - -From a6c4a8116c09243c39cc8d1e7ececcd8be0cfaf2 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Sun, 17 May 2020 22:14:03 +0900 -Subject: [PATCH 4/5] pkey/dsa: use high level EVP interface to generate - parameters and keys - -Implement PKey::DSA.new(size) and PKey::DSA.generate using -OpenSSL::PKey.generate_parameters and .generate_key instead of the low -level DSA functions. ---- - ext/openssl/lib/openssl/pkey.rb | 30 +++++++ - ext/openssl/ossl_pkey_dsa.c | 140 ++++++-------------------------- - test/openssl/test_pkey_dsa.rb | 23 ++---- - 3 files changed, 64 insertions(+), 129 deletions(-) - -diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb -index 3bef06e3b3..53ee52f98b 100644 ---- a/ext/openssl/lib/openssl/pkey.rb -+++ b/ext/openssl/lib/openssl/pkey.rb -@@ -88,6 +88,36 @@ def new(*args, &blk) # :nodoc: - - class DSA - include OpenSSL::Marshal -+ -+ class << self -+ # :call-seq: -+ # DSA.generate(size) -> dsa -+ # -+ # Creates a new DSA instance by generating a private/public key pair -+ # from scratch. -+ # -+ # See also OpenSSL::PKey.generate_parameters and -+ # OpenSSL::PKey.generate_key. -+ # -+ # +size+:: -+ # The desired key size in bits. -+ def generate(size, &blk) -+ dsaparams = OpenSSL::PKey.generate_parameters("DSA", { -+ "dsa_paramgen_bits" => size, -+ }, &blk) -+ OpenSSL::PKey.generate_key(dsaparams) -+ end -+ -+ # Handle DSA.new(size) 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 - - if defined?(EC) -diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c -index 0e68f7f27f..1c5a8a737e 100644 ---- a/ext/openssl/ossl_pkey_dsa.c -+++ b/ext/openssl/ossl_pkey_dsa.c -@@ -46,126 +46,39 @@ VALUE eDSAError; - /* - * Private - */ --struct dsa_blocking_gen_arg { -- DSA *dsa; -- int size; -- int *counter; -- unsigned long *h; -- BN_GENCB *cb; -- int result; --}; -- --static void * --dsa_blocking_gen(void *arg) --{ -- struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg; -- gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, NULL, 0, -- gen->counter, gen->h, gen->cb); -- return 0; --} -- --static DSA * --dsa_generate(int size) --{ -- struct ossl_generate_cb_arg cb_arg = { 0 }; -- struct dsa_blocking_gen_arg gen_arg; -- DSA *dsa = DSA_new(); -- BN_GENCB *cb = BN_GENCB_new(); -- int counter; -- unsigned long h; -- -- if (!dsa || !cb) { -- DSA_free(dsa); -- BN_GENCB_free(cb); -- ossl_raise(eDSAError, "malloc failure"); -- } -- -- if (rb_block_given_p()) -- cb_arg.yield = 1; -- BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); -- gen_arg.dsa = dsa; -- gen_arg.size = size; -- gen_arg.counter = &counter; -- gen_arg.h = &h; -- gen_arg.cb = cb; -- if (cb_arg.yield == 1) { -- /* we cannot release GVL when callback proc is supplied */ -- dsa_blocking_gen(&gen_arg); -- } else { -- /* there's a chance to unblock */ -- rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); -- } -- -- BN_GENCB_free(cb); -- if (!gen_arg.result) { -- DSA_free(dsa); -- if (cb_arg.state) { -- /* Clear OpenSSL error queue before re-raising. By the way, the -- * documentation of DSA_generate_parameters_ex() says the error code -- * can be obtained by ERR_get_error(), but the default -- * implementation, dsa_builtin_paramgen() doesn't put any error... */ -- ossl_clear_error(); -- rb_jump_tag(cb_arg.state); -- } -- ossl_raise(eDSAError, "DSA_generate_parameters_ex"); -- } -- -- if (!DSA_generate_key(dsa)) { -- DSA_free(dsa); -- ossl_raise(eDSAError, "DSA_generate_key"); -- } -- -- return dsa; --} -- --/* -- * call-seq: -- * DSA.generate(size) -> dsa -- * -- * Creates a new DSA instance by generating a private/public key pair -- * from scratch. -- * -- * === Parameters -- * * _size_ is an integer representing the desired key size. -- * -- */ --static VALUE --ossl_dsa_s_generate(VALUE klass, VALUE size) --{ -- EVP_PKEY *pkey; -- DSA *dsa; -- VALUE obj; -- -- obj = rb_obj_alloc(klass); -- GetPKey(obj, pkey); -- -- dsa = dsa_generate(NUM2INT(size)); -- if (!EVP_PKEY_assign_DSA(pkey, dsa)) { -- DSA_free(dsa); -- ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); -- } -- return obj; --} -- - /* - * call-seq: - * DSA.new -> dsa -- * DSA.new(size) -> dsa - * DSA.new(string [, pass]) -> dsa -+ * DSA.new(size) -> dsa - * - * Creates a new DSA instance by reading an existing key from _string_. - * -- * === Parameters -- * * _size_ is an integer representing the desired key size. -- * * _string_ contains a DER or PEM encoded key. -- * * _pass_ is a string that contains an optional password. -+ * If called without arguments, creates a new instance with no key components -+ * set. They can be set individually by #set_pqg and #set_key. - * -- * === Examples -- * DSA.new -> dsa -- * DSA.new(1024) -> dsa -- * DSA.new(File.read('dsa.pem')) -> dsa -- * DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa -+ * If called with a String, tries to parse as DER or PEM encoding of a \DSA key. -+ * See also OpenSSL::PKey.read which can parse keys of any kinds. -+ * -+ * If called with a number, generates random parameters and a key pair. This -+ * form works as an alias of DSA.generate. -+ * -+ * +string+:: -+ * A String that contains a DER or PEM encoded key. -+ * +pass+:: -+ * A String that contains an optional password. -+ * +size+:: -+ * See DSA.generate. - * -+ * Examples: -+ * p OpenSSL::PKey::DSA.new(1024) -+ * #=> # -+ * -+ * p OpenSSL::PKey::DSA.new(File.read('dsa.pem')) -+ * #=> # -+ * -+ * p OpenSSL::PKey::DSA.new(File.read('dsa.pem'), 'mypassword') -+ * #=> # - */ - static VALUE - ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) -@@ -176,15 +89,13 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) - VALUE arg, pass; - - GetPKey(self, pkey); -+ /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); - if (argc == 0) { - dsa = DSA_new(); - if (!dsa) - ossl_raise(eDSAError, "DSA_new"); - } -- else if (argc == 1 && RB_INTEGER_TYPE_P(arg)) { -- dsa = dsa_generate(NUM2INT(arg)); -- } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); -@@ -553,7 +464,6 @@ Init_ossl_dsa(void) - */ - cDSA = rb_define_class_under(mPKey, "DSA", cPKey); - -- rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1); - rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1); - rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1); - -diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb -index 4bf8a7b374..85bb6ec0ae 100644 ---- a/test/openssl/test_pkey_dsa.rb -+++ b/test/openssl/test_pkey_dsa.rb -@@ -5,31 +5,26 @@ - - class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase - def test_private -- key = OpenSSL::PKey::DSA.new(256) -- assert(key.private?) -+ key = Fixtures.pkey("dsa1024") -+ assert_equal true, key.private? - key2 = OpenSSL::PKey::DSA.new(key.to_der) -- assert(key2.private?) -+ assert_equal true, key2.private? - key3 = key.public_key -- assert(!key3.private?) -+ assert_equal false, key3.private? - key4 = OpenSSL::PKey::DSA.new(key3.to_der) -- assert(!key4.private?) -+ assert_equal false, key4.private? - end - - def test_new -- key = OpenSSL::PKey::DSA.new 256 -+ key = OpenSSL::PKey::DSA.new(2048) - pem = key.public_key.to_pem - OpenSSL::PKey::DSA.new pem -- if $0 == __FILE__ -- assert_nothing_raised { -- key = OpenSSL::PKey::DSA.new 2048 -- } -- end - end - - def test_new_break -- assert_nil(OpenSSL::PKey::DSA.new(512) { break }) -+ assert_nil(OpenSSL::PKey::DSA.new(2048) { break }) - assert_raise(RuntimeError) do -- OpenSSL::PKey::DSA.new(512) { raise } -+ OpenSSL::PKey::DSA.new(2048) { raise } - end - end - -@@ -184,7 +179,7 @@ def test_read_DSAPublicKey_pem - end - - def test_dup -- key = OpenSSL::PKey::DSA.new(256) -+ key = Fixtures.pkey("dsa1024") - key2 = key.dup - assert_equal key.params, key2.params - key2.set_pqg(key2.p + 1, key2.q, key2.g) --- -2.32.0 - - -From ba5a3a5c3eabf969f5cd2232b022e440af803b5b Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 5 Apr 2021 00:39:04 +0900 -Subject: [PATCH 5/5] pkey: remove unused ossl_generate_cb_2() helper function - -The previous series of commits re-implemented key generation with the -low level API with the EVP API. The BN_GENCB-based callback function is -no longer used. ---- - ext/openssl/extconf.rb | 3 -- - ext/openssl/openssl_missing.h | 12 ------ - ext/openssl/ossl_pkey.c | 73 +++++++---------------------------- - ext/openssl/ossl_pkey.h | 8 ---- - 4 files changed, 15 insertions(+), 81 deletions(-) - -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index 693e55cd97..b3c6647faf 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -136,9 +136,6 @@ def find_openssl_library - $defs.push("-DHAVE_OPAQUE_OPENSSL") - end - have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API") --have_func("BN_GENCB_new") --have_func("BN_GENCB_free") --have_func("BN_GENCB_get_arg") - have_func("EVP_MD_CTX_new") - have_func("EVP_MD_CTX_free") - have_func("EVP_MD_CTX_pkey_ctx") -diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h -index 7d218f86f5..e575415f49 100644 ---- a/ext/openssl/openssl_missing.h -+++ b/ext/openssl/openssl_missing.h -@@ -34,18 +34,6 @@ int ossl_EC_curve_nist2nid(const char *); - #endif - - /* added in 1.1.0 */ --#if !defined(HAVE_BN_GENCB_NEW) --# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) --#endif -- --#if !defined(HAVE_BN_GENCB_FREE) --# define BN_GENCB_free(cb) OPENSSL_free(cb) --#endif -- --#if !defined(HAVE_BN_GENCB_GET_ARG) --# define BN_GENCB_get_arg(cb) (cb)->arg --#endif -- - #if !defined(HAVE_EVP_MD_CTX_NEW) - # define EVP_MD_CTX_new EVP_MD_CTX_create - #endif -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index d76f0600d1..f9282b9417 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -17,64 +17,6 @@ VALUE cPKey; - VALUE ePKeyError; - static ID id_private_q; - --/* -- * callback for generating keys -- */ --static VALUE --call_check_ints0(VALUE arg) --{ -- rb_thread_check_ints(); -- return Qnil; --} -- --static void * --call_check_ints(void *arg) --{ -- int state; -- rb_protect(call_check_ints0, Qnil, &state); -- return (void *)(VALUE)state; --} -- --int --ossl_generate_cb_2(int p, int n, BN_GENCB *cb) --{ -- VALUE ary; -- struct ossl_generate_cb_arg *arg; -- int state; -- -- arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb); -- if (arg->yield) { -- ary = rb_ary_new2(2); -- rb_ary_store(ary, 0, INT2NUM(p)); -- rb_ary_store(ary, 1, INT2NUM(n)); -- -- /* -- * can be break by raising exception or 'break' -- */ -- rb_protect(rb_yield, ary, &state); -- if (state) { -- arg->state = state; -- return 0; -- } -- } -- if (arg->interrupted) { -- arg->interrupted = 0; -- state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL); -- if (state) { -- arg->state = state; -- return 0; -- } -- } -- return 1; --} -- --void --ossl_generate_cb_stop(void *ptr) --{ -- struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr; -- arg->interrupted = 1; --} -- - static void - ossl_evp_pkey_free(void *ptr) - { -@@ -257,6 +199,21 @@ pkey_gen_cb_yield(VALUE ctx_v) - return rb_yield_values2(info_num, argv); - } - -+static VALUE -+call_check_ints0(VALUE arg) -+{ -+ rb_thread_check_ints(); -+ return Qnil; -+} -+ -+static void * -+call_check_ints(void *arg) -+{ -+ int state; -+ rb_protect(call_check_ints0, Qnil, &state); -+ return (void *)(VALUE)state; -+} -+ - static int - pkey_gen_cb(EVP_PKEY_CTX *ctx) - { -diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h -index 7dbaed47bc..629c16ae1f 100644 ---- a/ext/openssl/ossl_pkey.h -+++ b/ext/openssl/ossl_pkey.h -@@ -35,14 +35,6 @@ extern const rb_data_type_t ossl_evp_pkey_type; - } \ - } while (0) - --struct ossl_generate_cb_arg { -- int yield; -- int interrupted; -- int state; --}; --int ossl_generate_cb_2(int p, int n, BN_GENCB *cb); --void ossl_generate_cb_stop(void *ptr); -- - VALUE ossl_pkey_new(EVP_PKEY *); - void ossl_pkey_check_public_key(const EVP_PKEY *); - EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); --- -2.32.0 - diff --git a/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch b/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch deleted file mode 100644 index 512be18..0000000 --- a/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch +++ /dev/null @@ -1,359 +0,0 @@ -From bcab8c3cd877506de75f50e0f9ed98827ed554b0 Mon Sep 17 00:00:00 2001 -From: Peter Zhu -Date: Tue, 23 Feb 2021 16:28:56 -0500 -Subject: [PATCH] Use mmap for allocating heap pages - ---- - configure.ac | 16 ++++ - gc.c | 149 ++++++++++++++++++++++++++--------- - test/ruby/test_gc_compact.rb | 41 ++++++---- - 3 files changed, 155 insertions(+), 51 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 2dcebdde9f..b1b190004d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1944,6 +1944,7 @@ AC_CHECK_FUNCS(memmem) - AC_CHECK_FUNCS(mkfifo) - AC_CHECK_FUNCS(mknod) - AC_CHECK_FUNCS(mktime) -+AC_CHECK_FUNCS(mmap) - AC_CHECK_FUNCS(openat) - AC_CHECK_FUNCS(pipe2) - AC_CHECK_FUNCS(poll) -@@ -2666,6 +2667,21 @@ main(int argc, char *argv[]) - rb_cv_fork_with_pthread=yes)]) - test x$rb_cv_fork_with_pthread = xyes || AC_DEFINE(CANNOT_FORK_WITH_PTHREAD) - ]) -+ -+AC_CHECK_HEADERS([sys/user.h]) -+AS_IF([test "x$ac_cv_func_mmap" = xyes], [ -+ AC_CACHE_CHECK([whether PAGE_SIZE is compile-time const], rb_cv_const_page_size, -+ [malloc_headers=`sed -n '/MALLOC_HEADERS_BEGIN/,/MALLOC_HEADERS_END/p' ${srcdir}/gc.c` -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$malloc_headers -+ typedef char conftest_page[PAGE_SIZE]; -+ ]], [[]])], -+ [rb_cv_const_page_size=yes], -+ [rb_cv_const_page_size=no])]) -+]) -+AS_IF([test "x$rb_cv_const_page_size" = xyes], -+ [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 1)], -+ [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 0)] -+) - } - - : "runtime section" && { -diff --git a/gc.c b/gc.c -index f6acf3e117..6f8e5f242d 100644 ---- a/gc.c -+++ b/gc.c -@@ -32,6 +32,7 @@ - #include - #include - -+/* MALLOC_HEADERS_BEGIN */ - #ifndef HAVE_MALLOC_USABLE_SIZE - # ifdef _WIN32 - # define HAVE_MALLOC_USABLE_SIZE -@@ -54,6 +55,12 @@ - # endif - #endif - -+#if !defined(PAGE_SIZE) && defined(HAVE_SYS_USER_H) -+/* LIST_HEAD conflicts with sys/queue.h on macOS */ -+# include -+#endif -+/* MALLOC_HEADERS_END */ -+ - #ifdef HAVE_SYS_TIME_H - # include - #endif -@@ -821,6 +828,25 @@ enum { - HEAP_PAGE_BITMAP_SIZE = (BITS_SIZE * HEAP_PAGE_BITMAP_LIMIT), - HEAP_PAGE_BITMAP_PLANES = 4 /* RGENGC: mark, unprotected, uncollectible, marking */ - }; -+#define HEAP_PAGE_ALIGN (1 << HEAP_PAGE_ALIGN_LOG) -+#define HEAP_PAGE_SIZE HEAP_PAGE_ALIGN -+ -+#ifdef HAVE_MMAP -+# if HAVE_CONST_PAGE_SIZE -+/* If we have the HEAP_PAGE and it is a constant, then we can directly use it. */ -+static const bool USE_MMAP_ALIGNED_ALLOC = (PAGE_SIZE <= HEAP_PAGE_SIZE); -+# elif defined(PAGE_MAX_SIZE) && (PAGE_MAX_SIZE <= HEAP_PAGE_SIZE) -+/* PAGE_SIZE <= HEAP_PAGE_SIZE */ -+static const bool USE_MMAP_ALIGNED_ALLOC = true; -+# else -+/* Otherwise, fall back to determining if we can use mmap during runtime. */ -+# define USE_MMAP_ALIGNED_ALLOC (use_mmap_aligned_alloc != false) -+ -+static bool use_mmap_aligned_alloc; -+# endif -+#elif !defined(__MINGW32__) && !defined(_WIN32) -+static const bool USE_MMAP_ALIGNED_ALLOC = false; -+#endif - - struct heap_page { - short total_slots; -@@ -1760,14 +1786,14 @@ heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pag - heap->total_slots -= page->total_slots; - } - --static void rb_aligned_free(void *ptr); -+static void rb_aligned_free(void *ptr, size_t size); - - static void - heap_page_free(rb_objspace_t *objspace, struct heap_page *page) - { - heap_allocated_pages--; - objspace->profile.total_freed_pages++; -- rb_aligned_free(GET_PAGE_BODY(page->start)); -+ rb_aligned_free(GET_PAGE_BODY(page->start), HEAP_PAGE_SIZE); - free(page); - } - -@@ -1819,7 +1845,7 @@ heap_page_allocate(rb_objspace_t *objspace) - /* assign heap_page entry */ - page = calloc1(sizeof(struct heap_page)); - if (page == 0) { -- rb_aligned_free(page_body); -+ rb_aligned_free(page_body, HEAP_PAGE_SIZE); - rb_memerror(); - } - -@@ -3159,15 +3185,18 @@ Init_heap(void) - { - rb_objspace_t *objspace = &rb_objspace; - --#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) -- /* If Ruby's heap pages are not a multiple of the system page size, we -- * cannot use mprotect for the read barrier, so we must disable automatic -- * compaction. */ -- int pagesize; -- pagesize = (int)sysconf(_SC_PAGE_SIZE); -- if ((HEAP_PAGE_SIZE % pagesize) != 0) { -- ruby_enable_autocompact = 0; -- } -+#if defined(HAVE_MMAP) && !HAVE_CONST_PAGE_SIZE && !defined(PAGE_MAX_SIZE) -+ /* Need to determine if we can use mmap at runtime. */ -+# ifdef PAGE_SIZE -+ /* If the PAGE_SIZE macro can be used. */ -+ use_mmap_aligned_alloc = PAGE_SIZE <= HEAP_PAGE_SIZE; -+# elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) -+ /* If we can use sysconf to determine the page size. */ -+ use_mmap_aligned_alloc = sysconf(_SC_PAGE_SIZE) <= HEAP_PAGE_SIZE; -+# else -+ /* Otherwise we can't determine the system page size, so don't use mmap. */ -+ use_mmap_aligned_alloc = FALSE; -+# endif - #endif - - objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL); -@@ -8533,6 +8562,14 @@ gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE - - /* For now, compact implies full mark / sweep, so ignore other flags */ - if (RTEST(compact)) { -+ /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for -+ * the read barrier, so we must disable compaction. */ -+#if !defined(__MINGW32__) && !defined(_WIN32) -+ if (!USE_MMAP_ALIGNED_ALLOC) { -+ rb_raise(rb_eNotImpError, "Compaction isn't available on this platform"); -+ } -+#endif -+ - reason |= GPR_FLAG_COMPACT; - } else { - if (!RTEST(full_mark)) reason &= ~GPR_FLAG_FULL_MARK; -@@ -9944,16 +9981,14 @@ gc_disable(rb_execution_context_t *ec, VALUE _) - static VALUE - gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v) - { --#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) -- /* If Ruby's heap pages are not a multiple of the system page size, we -- * cannot use mprotect for the read barrier, so we must disable automatic -- * compaction. */ -- int pagesize; -- pagesize = (int)sysconf(_SC_PAGE_SIZE); -- if ((HEAP_PAGE_SIZE % pagesize) != 0) { -+ /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for -+ * the read barrier, so we must disable automatic compaction. */ -+#if !defined(__MINGW32__) && !defined(_WIN32) -+ if (!USE_MMAP_ALIGNED_ALLOC) { - rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform"); - } - #endif -+ - ruby_enable_autocompact = RTEST(v); - return v; - } -@@ -10350,22 +10385,54 @@ rb_aligned_malloc(size_t alignment, size_t size) - #elif defined _WIN32 - void *_aligned_malloc(size_t, size_t); - res = _aligned_malloc(size, alignment); --#elif defined(HAVE_POSIX_MEMALIGN) -- if (posix_memalign(&res, alignment, size) == 0) { -- return res; -+#else -+ if (USE_MMAP_ALIGNED_ALLOC) { -+ GC_ASSERT(alignment % sysconf(_SC_PAGE_SIZE) == 0); -+ -+ char *ptr = mmap(NULL, alignment + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if (ptr == MAP_FAILED) { -+ return NULL; -+ } -+ -+ char *aligned = ptr + alignment; -+ aligned -= ((VALUE)aligned & (alignment - 1)); -+ GC_ASSERT(aligned > ptr); -+ GC_ASSERT(aligned <= ptr + alignment); -+ -+ size_t start_out_of_range_size = aligned - ptr; -+ GC_ASSERT(start_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0); -+ if (start_out_of_range_size > 0) { -+ if (munmap(ptr, start_out_of_range_size)) { -+ rb_bug("rb_aligned_malloc: munmap failed for start"); -+ } -+ } -+ -+ size_t end_out_of_range_size = alignment - start_out_of_range_size; -+ GC_ASSERT(end_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0); -+ if (end_out_of_range_size > 0) { -+ if (munmap(aligned + size, end_out_of_range_size)) { -+ rb_bug("rb_aligned_malloc: munmap failed for end"); -+ } -+ } -+ -+ res = (void *)aligned; - } - else { -- return NULL; -+# if defined(HAVE_POSIX_MEMALIGN) -+ if (posix_memalign(&res, alignment, size) != 0) { -+ return NULL; -+ } -+# elif defined(HAVE_MEMALIGN) -+ res = memalign(alignment, size); -+# else -+ char* aligned; -+ res = malloc(alignment + size + sizeof(void*)); -+ aligned = (char*)res + alignment + sizeof(void*); -+ aligned -= ((VALUE)aligned & (alignment - 1)); -+ ((void**)aligned)[-1] = res; -+ res = (void*)aligned; -+# endif - } --#elif defined(HAVE_MEMALIGN) -- res = memalign(alignment, size); --#else -- char* aligned; -- res = malloc(alignment + size + sizeof(void*)); -- aligned = (char*)res + alignment + sizeof(void*); -- aligned -= ((VALUE)aligned & (alignment - 1)); -- ((void**)aligned)[-1] = res; -- res = (void*)aligned; - #endif - - /* alignment must be a power of 2 */ -@@ -10375,16 +10442,26 @@ rb_aligned_malloc(size_t alignment, size_t size) - } - - static void --rb_aligned_free(void *ptr) -+rb_aligned_free(void *ptr, size_t size) - { - #if defined __MINGW32__ - __mingw_aligned_free(ptr); - #elif defined _WIN32 - _aligned_free(ptr); --#elif defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN) -- free(ptr); - #else -- free(((void**)ptr)[-1]); -+ if (USE_MMAP_ALIGNED_ALLOC) { -+ GC_ASSERT(size % sysconf(_SC_PAGE_SIZE) == 0); -+ if (munmap(ptr, size)) { -+ rb_bug("rb_aligned_free: munmap failed"); -+ } -+ } -+ else { -+# if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN) -+ free(ptr); -+# else -+ free(((void**)ptr)[-1]); -+# endif -+ } - #endif - } - -diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb -index 4a8cff33f4..f5cab55ba7 100644 ---- a/test/ruby/test_gc_compact.rb -+++ b/test/ruby/test_gc_compact.rb -@@ -4,12 +4,32 @@ - require 'etc' - - class TestGCCompact < Test::Unit::TestCase -- class AutoCompact < Test::Unit::TestCase -+ module SupportsCompact - def setup - skip "autocompact not supported on this platform" unless supports_auto_compact? - super - end - -+ private -+ -+ def supports_auto_compact? -+ return true unless defined?(Etc::SC_PAGE_SIZE) -+ -+ begin -+ return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0 -+ rescue NotImplementedError -+ rescue ArgumentError -+ end -+ -+ true -+ end -+ end -+ -+ include SupportsCompact -+ -+ class AutoCompact < Test::Unit::TestCase -+ include SupportsCompact -+ - def test_enable_autocompact - before = GC.auto_compact - GC.auto_compact = true -@@ -59,26 +79,17 @@ def test_implicit_compaction_does_something - ensure - GC.auto_compact = before - end -- -- private -- -- def supports_auto_compact? -- return true unless defined?(Etc::SC_PAGE_SIZE) -- -- begin -- return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0 -- rescue NotImplementedError -- rescue ArgumentError -- end -- -- true -- end - end - - def os_page_size - return true unless defined?(Etc::SC_PAGE_SIZE) - end - -+ def setup -+ skip "autocompact not supported on this platform" unless supports_auto_compact? -+ super -+ end -+ - def test_gc_compact_stats - list = [] - --- -2.30.1 (Apple Git-130) - diff --git a/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch b/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch deleted file mode 100644 index b8f727d..0000000 --- a/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a9977ba2f9863e3fb1b2346589ebbca67d80536c Mon Sep 17 00:00:00 2001 -From: Nobuyoshi Nakada -Date: Sat, 14 Aug 2021 10:08:19 +0900 -Subject: [PATCH] Constified addr2line.c - ---- - addr2line.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/addr2line.c b/addr2line.c -index 8ee4416650d3..fed1a8da84e5 100644 ---- a/addr2line.c -+++ b/addr2line.c -@@ -1138,12 +1138,12 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa - set_uint_value(v, read_uleb128(reader)); - break; - case DW_FORM_ref_addr: -- if (reader->address_size == 4) { -+ if (reader->format == 4) { - set_uint_value(v, read_uint32(&reader->p)); -- } else if (reader->address_size == 8) { -+ } else if (reader->format == 8) { - set_uint_value(v, read_uint64(&reader->p)); - } else { -- fprintf(stderr,"unknown address_size:%d", reader->address_size); -+ fprintf(stderr,"unknown format:%d", reader->format); - abort(); - } - break; diff --git a/ruby-3.1.0-test-openssl-test_digest-do-not-test-constants-for-l.patch b/ruby-3.1.0-test-openssl-test_digest-do-not-test-constants-for-l.patch deleted file mode 100644 index 5f3445e..0000000 --- a/ruby-3.1.0-test-openssl-test_digest-do-not-test-constants-for-l.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b4b5eab2a5fd0e9ac62c01102dd26d0a433c5683 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 18 May 2020 02:17:28 +0900 -Subject: [PATCH] test/openssl/test_digest: do not test constants for legacy - algorithms - -Remove availability test for MD4 and RIPEMD160 as they are considered -legacy and may be missing depending on the compile-time options of -OpenSSL. OpenSSL 3.0 by default disables them. ---- - test/openssl/test_digest.rb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb -index 8d7046e831..84c128c12f 100644 ---- a/test/openssl/test_digest.rb -+++ b/test/openssl/test_digest.rb -@@ -54,7 +54,7 @@ def test_reset - end - - def test_digest_constants -- %w{MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name| -+ %w{MD5 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name| - assert_not_nil(OpenSSL::Digest.new(name)) - klass = OpenSSL::Digest.const_get(name.tr('-', '_')) - assert_not_nil(klass.new) --- -2.32.0 - diff --git a/ruby-3.1.0-test-openssl-test_pkcs12-fix-test-failures-with-Open.patch b/ruby-3.1.0-test-openssl-test_pkcs12-fix-test-failures-with-Open.patch deleted file mode 100644 index 80b73d2..0000000 --- a/ruby-3.1.0-test-openssl-test_pkcs12-fix-test-failures-with-Open.patch +++ /dev/null @@ -1,439 +0,0 @@ -From 9596788bdd2d061bef042485af14262e9fc4020c Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Thu, 13 Aug 2020 23:20:55 +0900 -Subject: [PATCH] test/openssl/test_pkcs12: fix test failures with OpenSSL 3.0 - -OpenSSL's PKCS12_create() by default uses pbewithSHAAnd40BitRC2-CBC for -encryption of the certificates. However, in OpenSSL 3.0, the algorithm -is part of the legacy provider and is not enabled by default. - -Specify another algorithm that is still in the default provider for -these test cases. ---- - test/openssl/test_pkcs12.rb | 297 ++++++++++++++++++------------------ - 1 file changed, 149 insertions(+), 148 deletions(-) - -diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb -index fdbe753b17..ec676743bc 100644 ---- a/test/openssl/test_pkcs12.rb -+++ b/test/openssl/test_pkcs12.rb -@@ -5,6 +5,9 @@ - - module OpenSSL - class TestPKCS12 < OpenSSL::TestCase -+ DEFAULT_PBE_PKEYS = "PBE-SHA1-3DES" -+ DEFAULT_PBE_CERTS = "PBE-SHA1-3DES" -+ - def setup - super - ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA") -@@ -14,47 +17,41 @@ def setup - ["subjectKeyIdentifier","hash",false], - ["authorityKeyIdentifier","keyid:always",false], - ] -- @cacert = issue_cert(ca, Fixtures.pkey("rsa2048"), 1, ca_exts, nil, nil) -+ ca_key = Fixtures.pkey("rsa-1") -+ @cacert = issue_cert(ca, ca_key, 1, ca_exts, nil, nil) - - inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA") -- inter_ca_key = OpenSSL::PKey.read <<-_EOS_ -------BEGIN RSA PRIVATE KEY----- --MIICXAIBAAKBgQDp7hIG0SFMG/VWv1dBUWziAPrNmkMXJgTCAoB7jffzRtyyN04K --oq/89HAszTMStZoMigQURfokzKsjpUp8OYCAEsBtt9d5zPndWMz/gHN73GrXk3LT --ZsxEn7Xv5Da+Y9F/Hx2QZUHarV5cdZixq2NbzWGwrToogOQMh2pxN3Z/0wIDAQAB --AoGBAJysUyx3olpsGzv3OMRJeahASbmsSKTXVLZvoIefxOINosBFpCIhZccAG6UV --5c/xCvS89xBw8aD15uUfziw3AuT8QPEtHCgfSjeT7aWzBfYswEgOW4XPuWr7EeI9 --iNHGD6z+hCN/IQr7FiEBgTp6A+i/hffcSdR83fHWKyb4M7TRAkEA+y4BNd668HmC --G5MPRx25n6LixuBxrNp1umfjEI6UZgEFVpYOg4agNuimN6NqM253kcTR94QNTUs5 --Kj3EhG1YWwJBAO5rUjiOyCNVX2WUQrOMYK/c1lU7fvrkdygXkvIGkhsPoNRzLPeA --HGJszKtrKD8bNihWpWNIyqKRHfKVD7yXT+kCQGCAhVCIGTRoypcDghwljHqLnysf --ci0h5ZdPcIqc7ODfxYhFsJ/Rql5ONgYsT5Ig/+lOQAkjf+TRYM4c2xKx2/8CQBvG --jv6dy70qDgIUgqzONtlmHeYyFzn9cdBO5sShdVYHvRHjFSMEXsosqK9zvW2UqvuK --FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3 --Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es= -------END RSA PRIVATE KEY----- -- _EOS_ -- @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, Fixtures.pkey("rsa2048")) -+ inter_ca_key = Fixtures.pkey("rsa-2") -+ @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, ca_key) - - exts = [ - ["keyUsage","digitalSignature",true], - ["subjectKeyIdentifier","hash",false], - ] - ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate") -- @mykey = Fixtures.pkey("rsa1024") -+ @mykey = Fixtures.pkey("rsa-3") - @mycert = issue_cert(ee, @mykey, 3, exts, @inter_cacert, inter_ca_key) - end - -- def test_create -+ def test_create_single_key_single_cert - pkcs12 = OpenSSL::PKCS12.create( - "omg", - "hello", - @mykey, -- @mycert -+ @mycert, -+ nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - ) -- assert_equal @mycert.to_der, pkcs12.certificate.to_der -+ assert_equal @mycert, pkcs12.certificate - assert_equal @mykey.to_der, pkcs12.key.to_der - assert_nil pkcs12.ca_certs -+ -+ der = pkcs12.to_der -+ decoded = OpenSSL::PKCS12.new(der, "omg") -+ assert_equal @mykey.to_der, decoded.key.to_der -+ assert_equal @mycert, decoded.certificate -+ assert_equal [], Array(decoded.ca_certs) - end - - def test_create_no_pass -@@ -62,14 +59,17 @@ def test_create_no_pass - nil, - "hello", - @mykey, -- @mycert -+ @mycert, -+ nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - ) -- assert_equal @mycert.to_der, pkcs12.certificate.to_der -+ assert_equal @mycert, pkcs12.certificate - assert_equal @mykey.to_der, pkcs12.key.to_der - assert_nil pkcs12.ca_certs - - decoded = OpenSSL::PKCS12.new(pkcs12.to_der) -- assert_cert @mycert, decoded.certificate -+ assert_equal @mycert, decoded.certificate - end - - def test_create_with_chain -@@ -80,7 +80,9 @@ def test_create_with_chain - "hello", - @mykey, - @mycert, -- chain -+ chain, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - ) - assert_equal chain, pkcs12.ca_certs - end -@@ -95,14 +97,16 @@ def test_create_with_chain_decode - "hello", - @mykey, - @mycert, -- chain -+ chain, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - ) - - decoded = OpenSSL::PKCS12.new(pkcs12.to_der, passwd) - assert_equal chain.size, decoded.ca_certs.size -- assert_include_cert @cacert, decoded.ca_certs -- assert_include_cert @inter_cacert, decoded.ca_certs -- assert_cert @mycert, decoded.certificate -+ assert_include decoded.ca_certs, @cacert -+ assert_include decoded.ca_certs, @inter_cacert -+ assert_equal @mycert, decoded.certificate - assert_equal @mykey.to_der, decoded.key.to_der - end - -@@ -126,8 +130,8 @@ def test_create_with_itr - @mykey, - @mycert, - [], -- nil, -- nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - 2048 - ) - -@@ -138,8 +142,8 @@ def test_create_with_itr - @mykey, - @mycert, - [], -- nil, -- nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - "omg" - ) - end -@@ -152,7 +156,8 @@ def test_create_with_mac_itr - @mykey, - @mycert, - [], -- nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - nil, - nil, - 2048 -@@ -165,148 +170,144 @@ def test_create_with_mac_itr - @mykey, - @mycert, - [], -- nil, -- nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, - nil, - "omg" - ) - end - end - -- def test_new_with_one_key_and_one_cert -- # generated with: -- # openssl version #=> OpenSSL 1.0.2h 3 May 2016 -- # openssl pkcs12 -in <@mycert> -inkey -export -out -- str = <<~EOF.unpack("m").first --MIIGQQIBAzCCBgcGCSqGSIb3DQEHAaCCBfgEggX0MIIF8DCCAu8GCSqGSIb3DQEH --BqCCAuAwggLcAgEAMIIC1QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIeZPM --Rh6KiXgCAggAgIICqL6O+LCZmBzdIg6mozPF3FpY0hVbWHvTNMiDHieW3CrAanhN --YCH2/wHqH8WpFpEWwF0qEEXAWjHsIlYB4Cfqo6b7XpuZe5eVESsjNTOTMF1JCUJj --A6iNefXmCFLync1JK5LUodRDhTlKLU1WPK20X9X4vuEwHn8wt5RUb8P0E+Xh6rpS --XC4LkZKT45zF3cJa/n5+dW65ohVGNVnF9D1bCNEKHMOllK1V9omutQ9slW88hpga --LGiFsJoFOb/ESGb78KO+bd6zbX1MdKdBV+WD6t1uF/cgU65y+2A4nXs1urda+MJ7 --7iVqiB7Vnc9cANTbAkTSGNyoUDVM/NZde782/8IvddLAzUZ2EftoRDke6PvuBOVL --ljBhNWmdamrtBqzuzVZCRdWq44KZkF2Xoc9asepwIkdVmntzQF7f1Z+Ta5yg6HFp --xnr7CuM+MlHEShXkMgYtHnwAq10fDMSXIvjhi/AA5XUAusDO3D+hbtcRDcJ4uUes --dm5dhQE2qJ02Ysn4aH3o1F3RYNOzrxejHJwl0D2TCE8Ww2X342xib57+z9u03ufj --jswhiMKxy67f1LhUMq3XrT3uV6kCVXk/KUOUPcXPlPVNA5JmZeFhMp6GrtB5xJJ9 --wwBZD8UL5A2U2Mxi2OZsdUBv8eo3jnjZ284aFpt+mCjIHrLW5O0jwY8OCwSlYUoY --IY00wlabX0s82kBcIQNZbC1RSV2267ro/7A0MClc8YQ/zWN0FKY6apgtUkHJI1cL --1dc77mhnjETjwW94iLMDFy4zQfVu7IfCBqOBzygRNnqqUG66UhTs1xFnWM0mWXl/ --Zh9+AMpbRLIPaKCktIjl5juzzm+KEgkhD+707XRCFIGUYGP5bSHzGaz8PK9hj0u1 --E2SpZHUvYOcawmxtA7pmpSxl5uQjMIIC+QYJKoZIhvcNAQcBoIIC6gSCAuYwggLi --MIIC3gYLKoZIhvcNAQwKAQKgggKmMIICojAcBgoqhkiG9w0BDAEDMA4ECKB338m8 --qSzHAgIIAASCAoACFhJeqA3xx+s1qIH6udNQYY5hAL6oz7SXoGwFhDiceSyJjmAD --Dby9XWM0bPl1Gj5nqdsuI/lAM++fJeoETk+rxw8q6Ofk2zUaRRE39qgpwBwSk44o --0SAFJ6bzHpc5CFh6sZmDaUX5Lm9GtjnGFmmsPTSJT5an5JuJ9WczGBEd0nSBQhJq --xHbTGZiN8i3SXcIH531Sub+CBIFWy5lyCKgDYh/kgJFGQAaWUOjLI+7dCEESonXn --F3Jh2uPbnDF9MGJyAFoNgWFhgSpi1cf6AUi87GY4Oyur88ddJ1o0D0Kz2uw8/bpG --s3O4PYnIW5naZ8mozzbnYByEFk7PoTwM7VhoFBfYNtBoAI8+hBnPY/Y71YUojEXf --SeX6QbtkIANfzS1XuFNKElShC3DPQIHpKzaatEsfxHfP+8VOav6zcn4mioao7NHA --x7Dp6R1enFGoQOq4UNjBT8YjnkG5vW8zQHW2dAHLTJBq6x2Fzm/4Pjo/8vM1FiGl --BQdW5vfDeJ/l6NgQm3xR9ka2E2HaDqIcj1zWbN8jy/bHPFJYuF/HH8MBV/ngMIXE --vFEW/ToYv8eif0+EpUtzBsCKD4a7qYYYh87RmEVoQU96q6m+UbhpD2WztYfAPkfo --OSL9j2QHhVczhL7OAgqNeM95pOsjA9YMe7exTeqK31LYnTX8oH8WJD1xGbRSJYgu --SY6PQbumcJkc/TFPn0GeVUpiDdf83SeG50lo/i7UKQi2l1hi5Y51fQhnBnyMr68D --llSZEvSWqfDxBJkBpeg6PIYvkTpEwKRJpVQoM3uYvdqVSSnW6rydqIb+snfOrlhd --f+xCtq9xr+kHeTSqLIDRRAnMfgFRhY3IBlj6MSUwIwYJKoZIhvcNAQkVMRYEFBdb --8XGWehZ6oPj56Pf/uId46M9AMDEwITAJBgUrDgMCGgUABBRvSCB04/f8f13pp2PF --vyl2WuMdEwQIMWFFphPkIUICAggA -- EOF -- p12 = OpenSSL::PKCS12.new(str, "abc123") -- -- assert_equal @mykey.to_der, p12.key.to_der -- assert_equal @mycert.subject.to_der, p12.certificate.subject.to_der -- assert_equal [], Array(p12.ca_certs) -- end -- - def test_new_with_no_keys - # generated with: -- # openssl pkcs12 -in <@mycert> -nokeys -export -out -+ # openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export - str = <<~EOF.unpack("m").first --MIIDHAIBAzCCAuIGCSqGSIb3DQEHAaCCAtMEggLPMIICyzCCAscGCSqGSIb3DQEH --BqCCArgwggK0AgEAMIICrQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIX4+W --irqwH40CAggAgIICgOaCyo+5+6IOVoGCCL80c50bkkzAwqdXxvkKExJSdcJz2uMU --0gRrKnZEjL5wrUsN8RwZu8DvgQTEhNEkKsUgM7AWainmN/EnwohIdHZAHpm6WD67 --I9kLGp0/DHrqZrV9P2dLfhXLUSQE8PI0tqZPZ8UEABhizkViw4eISTkrOUN7pGbN --Qtx/oqgitXDuX2polbxYYDwt9vfHZhykHoKgew26SeJyZfeMs/WZ6olEI4cQUAFr --mvYGuC1AxEGTo9ERmU8Pm16j9Hr9PFk50WYe+rnk9oX3wJogQ7XUWS5kYf7XRycd --NDkNiwV/ts94bbuaGZp1YA6I48FXpIc8b5fX7t9tY0umGaWy0bARe1L7o0Y89EPe --lMg25rOM7j3uPtFG8whbSfdETSy57UxzzTcJ6UwexeaK6wb2jqEmj5AOoPLWeaX0 --LyOAszR3v7OPAcjIDYZGdrbb3MZ2f2vo2pdQfu9698BrWhXuM7Odh73RLhJVreNI --aezNOAtPyBlvGiBQBGTzRIYHSLL5Y5aVj2vWLAa7hjm5qTL5C5mFdDIo6TkEMr6I --OsexNQofEGs19kr8nARXDlcbEimk2VsPj4efQC2CEXZNzURsKca82pa62MJ8WosB --DTFd8X06zZZ4nED50vLopZvyW4fyW60lELwOyThAdG8UchoAaz2baqP0K4de44yM --Y5/yPFDu4+GoimipJfbiYviRwbzkBxYW8+958ILh0RtagLbvIGxbpaym9PqGjOzx --ShNXjLK2aAFZsEizQ8kd09quJHU/ogq2cUXdqqhmOqPnUWrJVi/VCoRB3Pv1/lE4 --mrUgr2YZ11rYvBw6g5XvNvFcSc53OKyV7SLn0dwwMTAhMAkGBSsOAwIaBQAEFEWP --1WRQykaoD4uJCpTx/wv0SLLBBAiDKI26LJK7xgICCAA= -+MIIGJAIBAzCCBeoGCSqGSIb3DQEHAaCCBdsEggXXMIIF0zCCBc8GCSqGSIb3 -+DQEHBqCCBcAwggW8AgEAMIIFtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMw -+DgQIjv5c3OHvnBgCAggAgIIFiMJa8Z/w7errRvCQPXh9dGQz3eJaFq3S2gXD -+rh6oiwsgIRJZvYAWgU6ll9NV7N5SgvS2DDNVuc3tsP8TPWjp+bIxzS9qmGUV -+kYWuURWLMKhpF12ZRDab8jcIwBgKoSGiDJk8xHjx6L613/XcRM6ln3VeQK+C -+hlW5kXniNAUAgTft25Fn61Xa8xnhmsz/fk1ycGnyGjKCnr7Mgy7KV0C1vs23 -+18n8+b1ktDWLZPYgpmXuMFVh0o+HJTV3O86mkIhJonMcnOMgKZ+i8KeXaocN -+JQlAPBG4+HOip7FbQT/h6reXv8/J+hgjLfqAb5aV3m03rUX9mXx66nR1tQU0 -+Jq+XPfDh5+V4akIczLlMyyo/xZjI1/qupcMjr+giOGnGd8BA3cuXW+ueLQiA -+PpTp+DQLVHRfz9XTZbyqOReNEtEXvO9gOlKSEY5lp65ItXVEs2Oqyf9PfU9y -+DUltN6fCMilwPyyrsIBKXCu2ZLM5h65KVCXAYEX9lNqj9zrQ7vTqvCNN8RhS -+ScYouTX2Eqa4Z+gTZWLHa8RCQFoyP6hd+97/Tg2Gv2UTH0myQxIVcnpdi1wy -+cqb+er7tyKbcO96uSlUjpj/JvjlodtjJcX+oinEqGb/caj4UepbBwiG3vv70 -+63bS3jTsOLNjDRsR9if3LxIhLa6DW8zOJiGC+EvMD1o4dzHcGVpQ/pZWCHZC -++YiNJpQOBApiZluE+UZ0m3XrtHFQYk7xblTrh+FJF91wBsok0rZXLAKd8m4p -+OJsc7quCq3cuHRRTzJQ4nSe01uqbwGDAYwLvi6VWy3svU5qa05eDRmgzEFTG -+e84Gp/1LQCtpQFr4txkjFchO2whWS80KoQKqmLPyGm1D9Lv53Q4ZsKMgNihs -+rEepuaOZMKHl4yMAYFoOXZCAYzfbhN6b2phcFAHjMUHUw9e3F0QuDk9D0tsr -+riYTrkocqlOKfK4QTomx27O0ON2J6f1rtEojGgfl9RNykN7iKGzjS3914QjW -+W6gGiZejxHsDPEAa4gUp0WiSUSXtD5WJgoyAzLydR2dKWsQ4WlaUXi01CuGy -++xvncSn2nO3bbot8VD5H6XU1CjREVtnIfbeRYO/uofyLUP3olK5RqN6ne6Xo -+eXnJ/bjYphA8NGuuuvuW1SCITmINkZDLC9cGlER9+K65RR/DR3TigkexXMeN -+aJ70ivZYAl0OuhZt3TGIlAzS64TIoyORe3z7Ta1Pp9PZQarYJpF9BBIZIFor -+757PHHuQKRuugiRkp8B7v4eq1BQ+VeAxCKpyZ7XrgEtbY/AWDiaKcGPKPjc3 -+AqQraVeQm7kMBT163wFmZArCphzkDOI3bz2oEO8YArMgLq2Vto9jAZlqKyWr -+pi2bSJxuoP1aoD58CHcWMrf8/j1LVdQhKgHQXSik2ID0H2Wc/XnglhzlVFuJ -+JsNIW/EGJlZh/5WDez9U0bXqnBlu3uasPEOezdoKlcCmQlmTO5+uLHYLEtNA -+EH9MtnGZebi9XS5meTuS6z5LILt8O9IHZxmT3JRPHYj287FEzotlLdcJ4Ee5 -+enW41UHjLrfv4OaITO1hVuoLRGdzjESx/fHMWmxroZ1nVClxECOdT42zvIYJ -+J3xBZ0gppzQ5fjoYiKjJpxTflRxUuxshk3ih6VUoKtqj/W18tBQ3g5SOlkgT -+yCW8r74yZlfYmNrPyDMUQYpLUPWj2n71GF0KyPfTU5yOatRgvheh262w5BG3 -+omFY7mb3tCv8/U2jdMIoukRKacpZiagofz3SxojOJq52cHnCri+gTHBMX0cO -+j58ygfntHWRzst0pV7Ze2X3fdCAJ4DokH6bNJNthcgmolFJ/y3V1tJjgsdtQ -+7Pjn/vE6xUV0HXE2x4yoVYNirbAMIvkN/X+atxrN0dA4AchN+zGp8TAxMCEw -+CQYFKw4DAhoFAAQUQ+6XXkyhf6uYgtbibILN2IjKnOAECLiqoY45MPCrAgII -+AA== - EOF - p12 = OpenSSL::PKCS12.new(str, "abc123") - - assert_equal nil, p12.key - assert_equal nil, p12.certificate - assert_equal 1, p12.ca_certs.size -- assert_equal @mycert.subject.to_der, p12.ca_certs[0].subject.to_der -+ assert_equal @mycert.subject, p12.ca_certs[0].subject - end - - def test_new_with_no_certs - # generated with: -- # openssl pkcs12 -inkey -nocerts -export -out -+ # openssl pkcs12 -inkey fixtures/openssl/pkey/rsa-1.pem -nocerts -export - str = <<~EOF.unpack("m").first --MIIDJwIBAzCCAu0GCSqGSIb3DQEHAaCCAt4EggLaMIIC1jCCAtIGCSqGSIb3DQEH --AaCCAsMEggK/MIICuzCCArcGCyqGSIb3DQEMCgECoIICpjCCAqIwHAYKKoZIhvcN --AQwBAzAOBAg6AaYnJs84SwICCAAEggKAQzZH+fWSpcQYD1J7PsGSune85A++fLCQ --V7tacp2iv95GJkxwYmfTP176pJdgs00mceB9UJ/u9EX5nD0djdjjQjwo6sgKjY0q --cpVhZw8CMxw7kBD2dhtui0zT8z5hy03LePxsjEKsGiSbeVeeGbSfw/I6AAYbv+Uh --O/YPBGumeHj/D2WKnfsHJLQ9GAV3H6dv5VKYNxjciK7f/JEyZCuUQGIN64QFHDhJ --7fzLqd/ul3FZzJZO6a+dwvcgux09SKVXDRSeFmRCEX4b486iWhJJVspCo9P2KNne --ORrpybr3ZSwxyoICmjyo8gj0OSnEfdx9790Ej1takPqSA1wIdSdBLekbZqB0RBQg --DEuPOsXNo3QFi8ji1vu0WBRJZZSNC2hr5NL6lNR+DKxG8yzDll2j4W4BBIp22mAE --7QRX7kVxu17QJXQhOUac4Dd1qXmzebP8t6xkAxD9L7BWEN5OdiXWwSWGjVjMBneX --nYObi/3UT/aVc5WHMHK2BhCI1bwH51E6yZh06d5m0TQpYGUTWDJdWGBSrp3A+8jN --N2PMQkWBFrXP3smHoTEN4oZC4FWiPsIEyAkQsfKRhcV9lGKl2Xgq54ROTFLnwKoj --Z3zJScnq9qmNzvVZSMmDLkjLyDq0pxRxGKBvgouKkWY7VFFIwwBIJM39iDJ5NbBY --i1AQFTRsRSsZrNVPasCXrIq7bhMoJZb/YZOGBLNyJVqKUoYXhtwsajzSq54VlWft --JxsPayEd4Vi6O9EU1ahnj6qFEZiKFzsicgK2J1Rb8cYagrp0XWjHW0SBn5GVUWCg --GUokSFG/0JTdeYTo/sQuG4qNgJkOolRjpeI48Fciq5VUWLvVdKioXzAxMCEwCQYF --Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA== -+MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3 -+DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK -+KoZIhvcNAQwBAzAOBAjX5nN8jyRKwQICCAAEgglIBIRLHfiY1mNHpl3FdX6+ -+72L+ZOVXnlZ1MY9HSeg0RMkCJcm0mJ2UD7INUOGXvwpK9fr6WJUZM1IqTihQ -+1dM0crRC2m23aP7KtAlXh2DYD3otseDtwoN/NE19RsiJzeIiy5TSW1d47weU -++D4Ig/9FYVFPTDgMzdCxXujhvO/MTbZIjqtcS+IOyF+91KkXrHkfkGjZC7KS -+WRmYw9BBuIPQEewdTI35sAJcxT8rK7JIiL/9mewbSE+Z28Wq1WXwmjL3oZm9 -+lw6+f515b197GYEGomr6LQqJJamSYpwQbTGHonku6Tf3ylB4NLFqOnRCKE4K -+zRSSYIqJBlKHmQ4pDm5awoupHYxMZLZKZvXNYyYN3kV8r1iiNVlY7KBR4CsX -+rqUkXehRmcPnuqEMW8aOpuYe/HWf8PYI93oiDZjcEZMwW2IZFFrgBbqUeNCM -+CQTkjAYxi5FyoaoTnHrj/aRtdLOg1xIJe4KKcmOXAVMmVM9QEPNfUwiXJrE7 -+n42gl4NyzcZpxqwWBT++9TnQGZ/lEpwR6dzkZwICNQLdQ+elsdT7mumywP+1 -+WaFqg9kpurimaiBu515vJNp9Iqv1Nmke6R8Lk6WVRKPg4Akw0fkuy6HS+LyN -+ofdCfVUkPGN6zkjAxGZP9ZBwvXUbLRC5W3N5qZuAy5WcsS75z+oVeX9ePV63 -+cue23sClu8JSJcw3HFgPaAE4sfkQ4MoihPY5kezgT7F7Lw/j86S0ebrDNp4N -+Y685ec81NRHJ80CAM55f3kGCOEhoifD4VZrvr1TdHZY9Gm3b1RYaJCit2huF -+nlOfzeimdcv/tkjb6UsbpXx3JKkF2NFFip0yEBERRCdWRYMUpBRcl3ad6XHy -+w0pVTgIjTxGlbbtOCi3siqMOK0GNt6UgjoEFc1xqjsgLwU0Ta2quRu7RFPGM -+GoEwoC6VH23p9Hr4uTFOL0uHfkKWKunNN+7YPi6LT6IKmTQwrp+fTO61N6Xh -+KlqTpwESKsIJB2iMnc8wBkjXJtmG/e2n5oTqfhICIrxYmEb7zKDyK3eqeTj3 -+FhQh2t7cUIiqcT52AckUqniPmlE6hf82yBjhaQUPfi/ExTBtTDSmFfRPUzq+ -+Rlla4OHllPRzUXJExyansgCxZbPqlw46AtygSWRGcWoYAKUKwwoYjerqIV5g -+JoZICV9BOU9TXco1dHXZQTs/nnTwoRmYiL/Ly5XpvUAnQOhYeCPjBeFnPSBR -+R/hRNqrDH2MOV57v5KQIH2+mvy26tRG+tVGHmLMaOJeQkjLdxx+az8RfXIrH -+7hpAsoBb+g9jUDY1mUVavPk1T45GMpQH8u3kkzRvChfOst6533GyIZhE7FhN -+KanC6ACabVFDUs6P9pK9RPQMp1qJfpA0XJFx5TCbVbPkvnkZd8K5Tl/tzNM1 -+n32eRao4MKr9KDwoDL93S1yJgYTlYjy1XW/ewdedtX+B4koAoz/wSXDYO+GQ -+Zu6ZSpKSEHTRPhchsJ4oICvpriVaJkn0/Z7H3YjNMB9U5RR9+GiIg1wY1Oa1 -+S3WfuwrrI6eqfbQwj6PDNu3IKy6srEgvJwaofQALNBPSYWbauM2brc8qsD+t -+n8jC/aD1aMcy00+9t3H/RVCjEOb3yKfUpAldIkEA2NTTnZpoDQDXeNYU2F/W -+yhmFjJy8A0O4QOk2xnZK9kcxSRs0v8vI8HivvgWENoVPscsDC4742SSIe6SL -+f/T08reIX11f0K70rMtLhtFMQdHdYOTNl6JzhkHPLr/f9MEZsBEQx52depnF -+ARb3gXGbCt7BAi0OeCEBSbLr2yWuW4r55N0wRZSOBtgqgjsiHP7CDQSkbL6p -+FPlQS1do9gBSHiNYvsmN1LN5bG+mhcVb0UjZub4mL0EqGadjDfDdRJmWqlX0 -+r5dyMcOWQVy4O2cPqYFlcP9lk8buc5otcyVI2isrAFdlvBK29oK6jc52Aq5Q -+0b2ESDlgX8WRgiOPPxK8dySKEeuIwngCtJyNTecP9Ug06TDsu0znZGCXJ+3P -+8JOpykgA8EQdOZOYHbo76ZfB2SkklI5KeRA5IBjGs9G3TZ4PHLy2DIwsbWzS -+H1g01o1x264nx1cJ+eEgUN/KIiGFIib42RS8Af4D5e+Vj54Rt3axq+ag3kI+ -+53p8uotyu+SpvvXUP7Kv4xpQ/L6k41VM0rfrd9+DrlDVvSfxP2uh6I1TKF7A -+CT5n8zguMbng4PGjxvyPBM5k62t6hN5fuw6Af0aZFexh+IjB/5wFQ6onSz23 -+fBzMW4St7RgSs8fDg3lrM+5rwXiey1jxY1ddaxOoUsWRMvvdd7rZxRZQoN5v -+AcI5iMkK/vvpQgC/sfzhtXtrJ2XOPZ+GVgi7VcuDLKSkdFMcPbGzO8SdxUnS -+SLV5XTKqKND+Lrfx7DAoKi5wbDFHu5496/MHK5qP4tBe6sJ5bZc+KDJIH46e -+wTV1oWtB5tV4q46hOb5WRcn/Wjz3HSKaGZgx5QbK1MfKTzD5CTUn+ArMockX -+2wJhPnFK85U4rgv8iBuh9bRjyw+YaKf7Z3loXRiE1eRG6RzuPF0ZecFiDumk -+AC/VUXynJhzePBLqzrQj0exanACdullN+pSfHiRWBxR2VFUkjoFP5X45GK3z -+OstSH6FOkMVU4afqEmjsIwozDFIyin5EyWTtdhJe3szdJSGY23Tut+9hUatx -+9FDFLESOd8z3tyQSNiLk/Hib+e/lbjxqbXBG/p/oyvP3N999PLUPtpKqtYkV -+H0+18sNh9CVfojiJl44fzxe8yCnuefBjut2PxEN0EFRBPv9P2wWlmOxkPKUq -+NrCJP0rDj5aONLrNZPrR8bZNdIShkZ/rKkoTuA0WMZ+xUlDRxAupdMkWAlrz -+8IcwNcdDjPnkGObpN5Ctm3vK7UGSBmPeNqkXOYf3QTJ9gStJEd0F6+DzTN5C -+KGt1IyuGwZqL2Yk51FDIIkr9ykEnBMaA39LS7GFHEDNGlW+fKC7AzA0zfoOr -+fXZlHMBuqHtXqk3zrsHRqGGoocigg4ctrhD1UREYKj+eIj1TBiRdf7c6+COf -+NIOmej8pX3FmZ4ui+dDA8r2ctgsWHrb4A6iiH+v1DRA61GtoaA/tNRggewXW -+VXCZCGWyyTuyHGOqq5ozrv5MlzZLWD/KV/uDsAWmy20RAed1C4AzcXlpX25O -+M4SNl47g5VRNJRtMqokc8j6TjZrzMDEwITAJBgUrDgMCGgUABBRrkIRuS5qg -+BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA - EOF - p12 = OpenSSL::PKCS12.new(str, "abc123") - -- assert_equal @mykey.to_der, p12.key.to_der -+ assert_equal Fixtures.pkey("rsa-1").to_der, p12.key.to_der - assert_equal nil, p12.certificate - assert_equal [], Array(p12.ca_certs) - end - - def test_dup -- p12 = OpenSSL::PKCS12.create("pass", "name", @mykey, @mycert) -+ p12 = OpenSSL::PKCS12.create( -+ "pass", -+ "name", -+ @mykey, -+ @mycert, -+ nil, -+ DEFAULT_PBE_PKEYS, -+ DEFAULT_PBE_CERTS, -+ ) - assert_equal p12.to_der, p12.dup.to_der - end -- -- private -- def assert_cert expected, actual -- [ -- :subject, -- :issuer, -- :serial, -- :not_before, -- :not_after, -- ].each do |attribute| -- assert_equal expected.send(attribute), actual.send(attribute) -- end -- assert_equal expected.to_der, actual.to_der -- end -- -- def assert_include_cert cert, ary -- der = cert.to_der -- ary.each do |candidate| -- if candidate.to_der == der -- return true -- end -- end -- false -- end - end - end - --- -2.32.0 - diff --git a/ruby-3.1.0-test-openssl-test_pkey-use-EC-keys-for-PKey.generate.patch b/ruby-3.1.0-test-openssl-test_pkey-use-EC-keys-for-PKey.generate.patch deleted file mode 100644 index ac45842..0000000 --- a/ruby-3.1.0-test-openssl-test_pkey-use-EC-keys-for-PKey.generate.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 10d2216b2f35a31777a099d9f765b0b6ea34a63e Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 18 May 2020 02:35:35 +0900 -Subject: [PATCH] test/openssl/test_pkey: use EC keys for - PKey.generate_parameters tests - -OpenSSL 3.0 refuses to generate DSA parameters shorter than 2048 bits, -but generating 2048 bits parameters takes very long time. Let's use EC -in these test cases instead. ---- - test/openssl/test_pkey.rb | 27 +++++++++++---------------- - 1 file changed, 11 insertions(+), 16 deletions(-) - -diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb -index 3630458b3c..88a6e04581 100644 ---- a/test/openssl/test_pkey.rb -+++ b/test/openssl/test_pkey.rb -@@ -27,20 +27,16 @@ def test_generic_oid_inspect - end - - def test_s_generate_parameters -- # 512 is non-default; 1024 is used if 'dsa_paramgen_bits' is not specified -- # with OpenSSL 1.1.0. -- pkey = OpenSSL::PKey.generate_parameters("DSA", { -- "dsa_paramgen_bits" => 512, -- "dsa_paramgen_q_bits" => 256, -+ pkey = OpenSSL::PKey.generate_parameters("EC", { -+ "ec_paramgen_curve" => "secp384r1", - }) -- assert_instance_of OpenSSL::PKey::DSA, pkey -- assert_equal 512, pkey.p.num_bits -- assert_equal 256, pkey.q.num_bits -- assert_equal nil, pkey.priv_key -+ assert_instance_of OpenSSL::PKey::EC, pkey -+ assert_equal "secp384r1", pkey.group.curve_name -+ assert_equal nil, pkey.private_key - - # Invalid options are checked - assert_raise(OpenSSL::PKey::PKeyError) { -- OpenSSL::PKey.generate_parameters("DSA", "invalid" => "option") -+ OpenSSL::PKey.generate_parameters("EC", "invalid" => "option") - } - - # Parameter generation callback is called -@@ -59,14 +55,13 @@ def test_s_generate_key - # DSA key pair cannot be generated without parameters - OpenSSL::PKey.generate_key("DSA") - } -- pkey_params = OpenSSL::PKey.generate_parameters("DSA", { -- "dsa_paramgen_bits" => 512, -- "dsa_paramgen_q_bits" => 256, -+ pkey_params = OpenSSL::PKey.generate_parameters("EC", { -+ "ec_paramgen_curve" => "secp384r1", - }) - pkey = OpenSSL::PKey.generate_key(pkey_params) -- assert_instance_of OpenSSL::PKey::DSA, pkey -- assert_equal 512, pkey.p.num_bits -- assert_not_equal nil, pkey.priv_key -+ assert_instance_of OpenSSL::PKey::EC, pkey -+ assert_equal "secp384r1", pkey.group.curve_name -+ assert_not_equal nil, pkey.private_key - end - - def test_hmac_sign_verify --- -2.32.0 - diff --git a/ruby-3.1.0-test-openssl-test_ssl-relax-regex-to-match-OpenSSL-s.patch b/ruby-3.1.0-test-openssl-test_ssl-relax-regex-to-match-OpenSSL-s.patch deleted file mode 100644 index c9421bc..0000000 --- a/ruby-3.1.0-test-openssl-test_ssl-relax-regex-to-match-OpenSSL-s.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 05fd14aea7eff2a6911a6f529f1237276482c6e7 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Fri, 10 Jul 2020 13:56:38 +0900 -Subject: [PATCH] test/openssl/test_ssl: relax regex to match OpenSSL's error - message - -OpenSSL 3.0 slightly changed the error message for a certificate -verification failure when an untrusted self-signed certificate is found -in the chain. ---- - test/openssl/test_ssl.rb | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb -index 6095d545b5..9e9b8b9b69 100644 ---- a/test/openssl/test_ssl.rb -+++ b/test/openssl/test_ssl.rb -@@ -964,7 +964,9 @@ def test_connect_certificate_verify_failed_exception_message - start_server(ignore_listener_error: true) { |port| - ctx = OpenSSL::SSL::SSLContext.new - ctx.set_params -- assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) { -+ # OpenSSL <= 1.1.0: "self signed certificate in certificate chain" -+ # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain" -+ assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) { - server_connect(port, ctx) - } - } --- -2.32.0 - diff --git a/ruby-3.1.0-test-openssl-utils-remove-dup_public-helper-method.patch b/ruby-3.1.0-test-openssl-utils-remove-dup_public-helper-method.patch deleted file mode 100644 index 2019380..0000000 --- a/ruby-3.1.0-test-openssl-utils-remove-dup_public-helper-method.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 2c6797bc97d7c92284dc3c0ed27f97ace4e5cfb9 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Mon, 31 May 2021 11:44:05 +0900 -Subject: [PATCH] test/openssl/utils: remove dup_public helper method - -It uses deprecated PKey::{RSA,DSA,DH}#set_* methods, which will not -work with OpenSSL 3.0. The same can easily be achieved using -PKey#public_to_der regardless of the key kind. ---- - test/openssl/test_pkey_dh.rb | 8 +++++--- - test/openssl/test_pkey_dsa.rb | 15 +++++++++++---- - test/openssl/test_pkey_ec.rb | 15 +++++++++++---- - test/openssl/test_pkey_rsa.rb | 31 +++++++++++++++++-------------- - test/openssl/utils.rb | 26 -------------------------- - 5 files changed, 44 insertions(+), 51 deletions(-) - -diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb -index f80af8f841..757704caf6 100644 ---- a/test/openssl/test_pkey_dh.rb -+++ b/test/openssl/test_pkey_dh.rb -@@ -40,12 +40,14 @@ def test_derive_key - - def test_DHparams - dh1024 = Fixtures.pkey("dh1024") -+ dh1024params = dh1024.public_key -+ - asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Integer(dh1024.p), - OpenSSL::ASN1::Integer(dh1024.g) - ]) - key = OpenSSL::PKey::DH.new(asn1.to_der) -- assert_same_dh dup_public(dh1024), key -+ assert_same_dh dh1024params, key - - pem = <<~EOF - -----BEGIN DH PARAMETERS----- -@@ -55,9 +57,9 @@ def test_DHparams - -----END DH PARAMETERS----- - EOF - key = OpenSSL::PKey::DH.new(pem) -- assert_same_dh dup_public(dh1024), key -+ assert_same_dh dh1024params, key - key = OpenSSL::PKey.read(pem) -- assert_same_dh dup_public(dh1024), key -+ assert_same_dh dh1024params, key - - assert_equal asn1.to_der, dh1024.to_der - assert_equal pem, dh1024.export -diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb -index 147e50176b..0994607f21 100644 ---- a/test/openssl/test_pkey_dsa.rb -+++ b/test/openssl/test_pkey_dsa.rb -@@ -138,6 +138,8 @@ def test_DSAPrivateKey_encrypted - - def test_PUBKEY - dsa512 = Fixtures.pkey("dsa512") -+ dsa512pub = OpenSSL::PKey::DSA.new(dsa512.public_to_der) -+ - asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::ObjectId("DSA"), -@@ -153,7 +155,7 @@ def test_PUBKEY - ]) - key = OpenSSL::PKey::DSA.new(asn1.to_der) - assert_not_predicate key, :private? -- assert_same_dsa dup_public(dsa512), key -+ assert_same_dsa dsa512pub, key - - pem = <<~EOF - -----BEGIN PUBLIC KEY----- -@@ -166,10 +168,15 @@ def test_PUBKEY - -----END PUBLIC KEY----- - EOF - key = OpenSSL::PKey::DSA.new(pem) -- assert_same_dsa dup_public(dsa512), key -+ assert_same_dsa dsa512pub, key -+ -+ assert_equal asn1.to_der, key.to_der -+ assert_equal pem, key.export - -- assert_equal asn1.to_der, dup_public(dsa512).to_der -- assert_equal pem, dup_public(dsa512).export -+ assert_equal asn1.to_der, dsa512.public_to_der -+ assert_equal asn1.to_der, key.public_to_der -+ assert_equal pem, dsa512.public_to_pem -+ assert_equal pem, key.public_to_pem - end - - def test_read_DSAPublicKey_pem -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index 4b6df0290f..d62f1b5eb8 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -210,6 +210,8 @@ def test_ECPrivateKey_encrypted - - def test_PUBKEY - p256 = Fixtures.pkey("p256") -+ p256pub = OpenSSL::PKey::EC.new(p256.public_to_der) -+ - asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::ObjectId("id-ecPublicKey"), -@@ -221,7 +223,7 @@ def test_PUBKEY - ]) - key = OpenSSL::PKey::EC.new(asn1.to_der) - assert_not_predicate key, :private? -- assert_same_ec dup_public(p256), key -+ assert_same_ec p256pub, key - - pem = <<~EOF - -----BEGIN PUBLIC KEY----- -@@ -230,10 +232,15 @@ def test_PUBKEY - -----END PUBLIC KEY----- - EOF - key = OpenSSL::PKey::EC.new(pem) -- assert_same_ec dup_public(p256), key -+ assert_same_ec p256pub, key -+ -+ assert_equal asn1.to_der, key.to_der -+ assert_equal pem, key.export - -- assert_equal asn1.to_der, dup_public(p256).to_der -- assert_equal pem, dup_public(p256).export -+ assert_equal asn1.to_der, p256.public_to_der -+ assert_equal asn1.to_der, key.public_to_der -+ assert_equal pem, p256.public_to_pem -+ assert_equal pem, key.public_to_pem - end - - def test_ec_group -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index 5e127f5407..4548bdb2cf 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -201,7 +201,7 @@ def test_sign_verify_pss - - def test_encrypt_decrypt - rsapriv = Fixtures.pkey("rsa-1") -- rsapub = dup_public(rsapriv) -+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der) - - # Defaults to PKCS #1 v1.5 - raw = "data" -@@ -216,7 +216,7 @@ def test_encrypt_decrypt - - def test_encrypt_decrypt_legacy - rsapriv = Fixtures.pkey("rsa-1") -- rsapub = dup_public(rsapriv) -+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der) - - # Defaults to PKCS #1 v1.5 - raw = "data" -@@ -346,13 +346,15 @@ def test_RSAPrivateKey_encrypted - - def test_RSAPublicKey - rsa1024 = Fixtures.pkey("rsa1024") -+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der) -+ - asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Integer(rsa1024.n), - OpenSSL::ASN1::Integer(rsa1024.e) - ]) - key = OpenSSL::PKey::RSA.new(asn1.to_der) - assert_not_predicate key, :private? -- assert_same_rsa dup_public(rsa1024), key -+ assert_same_rsa rsa1024pub, key - - pem = <<~EOF - -----BEGIN RSA PUBLIC KEY----- -@@ -362,11 +364,13 @@ def test_RSAPublicKey - -----END RSA PUBLIC KEY----- - EOF - key = OpenSSL::PKey::RSA.new(pem) -- assert_same_rsa dup_public(rsa1024), key -+ assert_same_rsa rsa1024pub, key - end - - def test_PUBKEY - rsa1024 = Fixtures.pkey("rsa1024") -+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der) -+ - asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::ObjectId("rsaEncryption"), -@@ -381,7 +385,7 @@ def test_PUBKEY - ]) - key = OpenSSL::PKey::RSA.new(asn1.to_der) - assert_not_predicate key, :private? -- assert_same_rsa dup_public(rsa1024), key -+ assert_same_rsa rsa1024pub, key - - pem = <<~EOF - -----BEGIN PUBLIC KEY----- -@@ -392,10 +396,15 @@ def test_PUBKEY - -----END PUBLIC KEY----- - EOF - key = OpenSSL::PKey::RSA.new(pem) -- assert_same_rsa dup_public(rsa1024), key -+ assert_same_rsa rsa1024pub, key -+ -+ assert_equal asn1.to_der, key.to_der -+ assert_equal pem, key.export - -- assert_equal asn1.to_der, dup_public(rsa1024).to_der -- assert_equal pem, dup_public(rsa1024).export -+ assert_equal asn1.to_der, rsa1024.public_to_der -+ assert_equal asn1.to_der, key.public_to_der -+ assert_equal pem, rsa1024.public_to_pem -+ assert_equal pem, key.public_to_pem - end - - def test_pem_passwd -@@ -482,12 +491,6 @@ def test_private_encoding_encrypted - assert_same_rsa rsa1024, OpenSSL::PKey.read(pem, "abcdef") - end - -- def test_public_encoding -- rsa1024 = Fixtures.pkey("rsa1024") -- assert_equal dup_public(rsa1024).to_der, rsa1024.public_to_der -- assert_equal dup_public(rsa1024).to_pem, rsa1024.public_to_pem -- end -- - def test_dup - key = Fixtures.pkey("rsa1024") - key2 = key.dup -diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb -index c1d737b2ab..f664bd3074 100644 ---- a/test/openssl/utils.rb -+++ b/test/openssl/utils.rb -@@ -313,32 +313,6 @@ def check_component(base, test, keys) - assert_equal base.send(comp), test.send(comp) - } - end -- -- def dup_public(key) -- case key -- when OpenSSL::PKey::RSA -- rsa = OpenSSL::PKey::RSA.new -- rsa.set_key(key.n, key.e, nil) -- rsa -- when OpenSSL::PKey::DSA -- dsa = OpenSSL::PKey::DSA.new -- dsa.set_pqg(key.p, key.q, key.g) -- dsa.set_key(key.pub_key, nil) -- dsa -- when OpenSSL::PKey::DH -- dh = OpenSSL::PKey::DH.new -- dh.set_pqg(key.p, nil, key.g) -- dh -- else -- if defined?(OpenSSL::PKey::EC) && OpenSSL::PKey::EC === key -- ec = OpenSSL::PKey::EC.new(key.group) -- ec.public_key = key.public_key -- ec -- else -- raise "unknown key type" -- end -- end -- end - end - - module OpenSSL::Certs --- -2.32.0 - diff --git a/ruby-3.1.1-ossl_ocsp-use-null.patch b/ruby-3.1.1-ossl_ocsp-use-null.patch deleted file mode 100644 index d6d39ef..0000000 --- a/ruby-3.1.1-ossl_ocsp-use-null.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- ext/openssl/ossl_ocsp.c.orig 2022-04-07 16:40:13.263752886 +0200 -+++ ext/openssl/ossl_ocsp.c 2022-04-07 16:45:56.818971187 +0200 -@@ -382,7 +382,7 @@ - if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) -- md = EVP_sha1(); -+ md = NULL; - else - md = ossl_evp_get_digestbyname(digest); - if (NIL_P(certs)) -@@ -1033,7 +1033,7 @@ - if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) -- md = EVP_sha1(); -+ md = NULL; - else - md = ossl_evp_get_digestbyname(digest); - if (NIL_P(certs)) ---- test/openssl/test_ocsp.rb.orig 2022-04-08 08:20:31.400739869 +0200 -+++ test/openssl/test_ocsp.rb 2022-04-08 08:20:37.208727488 +0200 -@@ -99,7 +99,7 @@ - request.sign(@cert, @cert_key, [@ca_cert], 0) - asn1 = OpenSSL::ASN1.decode(request.to_der) - assert_equal cid.to_der, asn1.value[0].value.find { |a| a.tag_class == :UNIVERSAL }.value[0].value[0].to_der -- assert_equal OpenSSL::ASN1.ObjectId("sha1WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der -+ assert_equal OpenSSL::ASN1.ObjectId("sha256WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der - assert_equal @cert.to_der, asn1.value[1].value[0].value[2].value[0].value[0].to_der - assert_equal @ca_cert.to_der, asn1.value[1].value[0].value[2].value[0].value[1].to_der - assert_equal asn1.to_der, OpenSSL::OCSP::Request.new(asn1.to_der).to_der diff --git a/ruby-3.1.2-ossl-tests-replace-sha1.patch b/ruby-3.1.2-ossl-tests-replace-sha1.patch deleted file mode 100644 index 176101c..0000000 --- a/ruby-3.1.2-ossl-tests-replace-sha1.patch +++ /dev/null @@ -1,647 +0,0 @@ -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb -index fedcb93..53ad621 100644 ---- a/ext/openssl/extconf.rb -+++ b/ext/openssl/extconf.rb -@@ -174,6 +174,7 @@ have_func("SSL_CTX_set_post_handshake_auth") - - # added in 1.1.1 - have_func("EVP_PKEY_check") -+have_func("SSL_CTX_set_ciphersuites") - - # added in 3.0.0 - have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") -diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h -index 4b51268..2ab8aea 100644 ---- a/ext/openssl/ossl.h -+++ b/ext/openssl/ossl.h -@@ -43,13 +43,13 @@ - #ifndef LIBRESSL_VERSION_NUMBER - # define OSSL_IS_LIBRESSL 0 - # define OSSL_OPENSSL_PREREQ(maj, min, pat) \ -- (OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) -+ (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) - # define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 - #else - # define OSSL_IS_LIBRESSL 1 - # define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 - # define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ -- (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) -+ (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) - #endif - - #if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) -diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c -index a61d3ee..0d3fa9a 100644 ---- a/ext/openssl/ossl_asn1.c -+++ b/ext/openssl/ossl_asn1.c -@@ -1510,7 +1510,7 @@ Init_ossl_asn1(void) - * - * An Array that stores the name of a given tag number. These names are - * the same as the name of the tag constant that is additionally defined, -- * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2. -+ * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2. - * - * == Example usage - * -diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c -index 2a4835a..24d0da4 100644 ---- a/ext/openssl/ossl_pkey.c -+++ b/ext/openssl/ossl_pkey.c -@@ -649,7 +649,7 @@ ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) - } - } - else { --#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) -+#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 5, 0) - if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, - ossl_pem_passwd_cb, - (void *)pass)) { -diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c -index 9a0682a..af262d9 100644 ---- a/ext/openssl/ossl_ssl.c -+++ b/ext/openssl/ossl_ssl.c -@@ -1025,27 +1025,13 @@ ossl_sslctx_get_ciphers(VALUE self) - return ary; - } - --/* -- * call-seq: -- * ctx.ciphers = "cipher1:cipher2:..." -- * ctx.ciphers = [name, ...] -- * ctx.ciphers = [[name, version, bits, alg_bits], ...] -- * -- * Sets the list of available cipher suites for this context. Note in a server -- * context some ciphers require the appropriate certificates. For example, an -- * RSA cipher suite can only be chosen when an RSA certificate is available. -- */ - static VALUE --ossl_sslctx_set_ciphers(VALUE self, VALUE v) -+build_cipher_string(VALUE v) - { -- SSL_CTX *ctx; - VALUE str, elem; - int i; - -- rb_check_frozen(self); -- if (NIL_P(v)) -- return v; -- else if (RB_TYPE_P(v, T_ARRAY)) { -+ if (RB_TYPE_P(v, T_ARRAY)) { - str = rb_str_new(0, 0); - for (i = 0; i < RARRAY_LEN(v); i++) { - elem = rb_ary_entry(v, i); -@@ -1059,14 +1059,67 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) - StringValue(str); - } - -+ return str; -+} -+ -+/* -+ * call-seq: -+ * ctx.ciphers = "cipher1:cipher2:..." -+ * ctx.ciphers = [name, ...] -+ * ctx.ciphers = [[name, version, bits, alg_bits], ...] -+ * -+ * Sets the list of available cipher suites for this context. Note in a server -+ * context some ciphers require the appropriate certificates. For example, an -+ * RSA cipher suite can only be chosen when an RSA certificate is available. -+ */ -+static VALUE -+ossl_sslctx_set_ciphers(VALUE self, VALUE v) -+{ -+ SSL_CTX *ctx; -+ VALUE str; -+ -+ rb_check_frozen(self); -+ if (NIL_P(v)) -+ return v; -+ -+ str = build_cipher_string(v); -+ - GetSSLCTX(self, ctx); -- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) { -+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) - ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); -- } - - return v; - } - -+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES -+/* -+ * call-seq: -+ * ctx.ciphersuites = "cipher1:cipher2:..." -+ * ctx.ciphersuites = [name, ...] -+ * ctx.ciphersuites = [[name, version, bits, alg_bits], ...] -+ * -+ * Sets the list of available TLSv1.3 cipher suites for this context. -+ */ -+static VALUE -+ossl_sslctx_set_ciphersuites(VALUE self, VALUE v) -+{ -+ SSL_CTX *ctx; -+ VALUE str; -+ -+ rb_check_frozen(self); -+ if (NIL_P(v)) -+ return v; -+ -+ str = build_cipher_string(v); -+ -+ GetSSLCTX(self, ctx); -+ if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str))) -+ ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites"); -+ -+ return v; -+} -+#endif -+ - #if !defined(OPENSSL_NO_EC) - /* - * call-seq: -@@ -2818,6 +2857,9 @@ Init_ossl_ssl(void) - ossl_sslctx_set_minmax_proto_version, 2); - rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); - rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); -+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES -+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1); -+#endif - rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1); - rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0); - rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1); -diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb -index 0fd7971..c79bc14 100644 ---- a/test/openssl/test_asn1.rb -+++ b/test/openssl/test_asn1.rb -@@ -14,7 +14,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase - ["keyUsage","keyCertSign, cRLSign",true], - ["subjectKeyIdentifier","hash",false], - ] -- dgst = OpenSSL::Digest.new('SHA1') -+ dgst = OpenSSL::Digest.new('SHA256') - cert = OpenSSL::TestUtils.issue_cert( - subj, key, s, exts, nil, nil, digest: dgst, not_before: now, not_after: now+3600) - -@@ -42,7 +42,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase - assert_equal(OpenSSL::ASN1::Sequence, sig.class) - assert_equal(2, sig.value.size) - assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class) -- assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid) -+ assert_equal("1.2.840.113549.1.1.11", sig.value[0].oid) - assert_equal(OpenSSL::ASN1::Null, sig.value[1].class) - - dn = tbs_cert.value[3] # issuer -@@ -189,7 +189,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase - assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class) - - assert_equal(OpenSSL::ASN1::BitString, sig_val.class) -- cululated_sig = key.sign(OpenSSL::Digest.new('SHA1'), tbs_cert.to_der) -+ cululated_sig = key.sign(OpenSSL::Digest.new('SHA256'), tbs_cert.to_der) - assert_equal(cululated_sig, sig_val.value) - end - -diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb -index ed3be86..383931b 100644 ---- a/test/openssl/test_ns_spki.rb -+++ b/test/openssl/test_ns_spki.rb -@@ -22,7 +22,7 @@ class OpenSSL::TestNSSPI < OpenSSL::TestCase - spki = OpenSSL::Netscape::SPKI.new - spki.challenge = "RandomString" - spki.public_key = key1.public_key -- spki.sign(key1, OpenSSL::Digest.new('SHA1')) -+ spki.sign(key1, OpenSSL::Digest.new('SHA256')) - assert(spki.verify(spki.public_key)) - assert(spki.verify(key1.public_key)) - assert(!spki.verify(key2.public_key)) -diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb -index 726b7db..08213df 100644 ---- a/test/openssl/test_pkey_dsa.rb -+++ b/test/openssl/test_pkey_dsa.rb -@@ -36,8 +36,8 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase - assert_equal true, dsa512.verify(OpenSSL::Digest.new('DSS1'), signature, data) - end - -- signature = dsa512.sign("SHA1", data) -- assert_equal true, dsa512.verify("SHA1", signature, data) -+ signature = dsa512.sign("SHA256", data) -+ assert_equal true, dsa512.verify("SHA256", signature, data) - - signature0 = (<<~'end;').unpack("m")[0] - MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/ -diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb -index ffe5a94..c06fe6f 100644 ---- a/test/openssl/test_pkey_ec.rb -+++ b/test/openssl/test_pkey_ec.rb -@@ -98,8 +98,8 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase - def test_sign_verify - p256 = Fixtures.pkey("p256") - data = "Sign me!" -- signature = p256.sign("SHA1", data) -- assert_equal true, p256.verify("SHA1", signature, data) -+ signature = p256.sign("SHA256", data) -+ assert_equal true, p256.verify("SHA256", signature, data) - - signature0 = (<<~'end;').unpack("m")[0] - MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq -diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb -index 4bb39ed..9e06e43 100644 ---- a/test/openssl/test_pkey_rsa.rb -+++ b/test/openssl/test_pkey_rsa.rb -@@ -80,8 +80,8 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase - def test_sign_verify - rsa1024 = Fixtures.pkey("rsa1024") - data = "Sign me!" -- signature = rsa1024.sign("SHA1", data) -- assert_equal true, rsa1024.verify("SHA1", signature, data) -+ signature = rsa1024.sign("SHA256", data) -+ assert_equal true, rsa1024.verify("SHA256", signature, data) - - signature0 = (<<~'end;').unpack("m")[0] - oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+ -@@ -113,10 +113,10 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase - def test_sign_verify_raw - key = Fixtures.pkey("rsa-1") - data = "Sign me!" -- hash = OpenSSL::Digest.digest("SHA1", data) -- signature = key.sign_raw("SHA1", hash) -- assert_equal true, key.verify_raw("SHA1", signature, hash) -- assert_equal true, key.verify("SHA1", signature, data) -+ hash = OpenSSL::Digest.digest("SHA256", data) -+ signature = key.sign_raw("SHA256", hash) -+ assert_equal true, key.verify_raw("SHA256", signature, hash) -+ assert_equal true, key.verify("SHA256", signature, data) - - # Too long data - assert_raise(OpenSSL::PKey::PKeyError) { -@@ -129,9 +129,9 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase - "rsa_pss_saltlen" => 20, - "rsa_mgf1_md" => "SHA256" - } -- sig_pss = key.sign_raw("SHA1", hash, pssopts) -- assert_equal true, key.verify("SHA1", sig_pss, data, pssopts) -- assert_equal true, key.verify_raw("SHA1", sig_pss, hash, pssopts) -+ sig_pss = key.sign_raw("SHA256", hash, pssopts) -+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts) -+ assert_equal true, key.verify_raw("SHA256", sig_pss, hash, pssopts) - end - - def test_sign_verify_raw_legacy -diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb -index a7607da..3ba8b39 100644 ---- a/test/openssl/test_ssl.rb -+++ b/test/openssl/test_ssl.rb -@@ -669,10 +669,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase - # buzz.example.net, respectively). ... - assert_equal(true, OpenSSL::SSL.verify_certificate_identity( - create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com')) -+ -+ # LibreSSL 3.5.0+ doesn't support other wildcard certificates -+ # (it isn't required to, as RFC states MAY, not MUST) -+ return if libressl?(3, 5, 0) -+ - assert_equal(true, OpenSSL::SSL.verify_certificate_identity( - create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com')) - assert_equal(true, OpenSSL::SSL.verify_certificate_identity( - create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com')) -+ - # Section 6.4.3 of RFC6125 states that client should NOT match identifier - # where wildcard is other than left-most label. - # -@@ -1556,8 +1562,101 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase - end - end - -+ def test_ciphersuites_method_tls_connection -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ if !tls13_supported? || !ssl_ctx.respond_to?(:ciphersuites=) -+ pend 'TLS 1.3 not supported' -+ end -+ -+ csuite = ['TLS_AES_128_GCM_SHA256', 'TLSv1.3', 128, 128] -+ inputs = [csuite[0], [csuite[0]], [csuite]] -+ -+ start_server do |port| -+ inputs.each do |input| -+ cli_ctx = OpenSSL::SSL::SSLContext.new -+ cli_ctx.min_version = cli_ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION -+ cli_ctx.ciphersuites = input -+ -+ server_connect(port, cli_ctx) do |ssl| -+ assert_equal('TLSv1.3', ssl.ssl_version) -+ if libressl?(3, 4, 0) && !libressl?(3, 5, 0) -+ assert_equal("AEAD-AES128-GCM-SHA256", ssl.cipher[0]) -+ else -+ assert_equal(csuite[0], ssl.cipher[0]) -+ end -+ ssl.puts('abc'); assert_equal("abc\n", ssl.gets) -+ end -+ end -+ end -+ end -+ -+ def test_ciphersuites_method_nil_argument -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) -+ -+ assert_nothing_raised { ssl_ctx.ciphersuites = nil } -+ end -+ -+ def test_ciphersuites_method_frozen_object -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) -+ -+ ssl_ctx.freeze -+ assert_raise(FrozenError) { ssl_ctx.ciphersuites = 'TLS_AES_256_GCM_SHA384' } -+ end -+ -+ def test_ciphersuites_method_bogus_csuite -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) -+ -+ assert_raise_with_message( -+ OpenSSL::SSL::SSLError, -+ /SSL_CTX_set_ciphersuites: no cipher match/i -+ ) { ssl_ctx.ciphersuites = 'BOGUS' } -+ end -+ -+ def test_ciphers_method_tls_connection -+ csuite = ['ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1.2', 256, 256] -+ inputs = [csuite[0], [csuite[0]], [csuite]] -+ -+ start_server do |port| -+ inputs.each do |input| -+ cli_ctx = OpenSSL::SSL::SSLContext.new -+ cli_ctx.min_version = cli_ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION -+ cli_ctx.ciphers = input -+ -+ server_connect(port, cli_ctx) do |ssl| -+ assert_equal('TLSv1.2', ssl.ssl_version) -+ assert_equal(csuite[0], ssl.cipher[0]) -+ ssl.puts('abc'); assert_equal("abc\n", ssl.gets) -+ end -+ end -+ end -+ end -+ -+ def test_ciphers_method_nil_argument -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ assert_nothing_raised { ssl_ctx.ciphers = nil } -+ end -+ -+ def test_ciphers_method_frozen_object -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ -+ ssl_ctx.freeze -+ assert_raise(FrozenError) { ssl_ctx.ciphers = 'ECDHE-RSA-AES128-SHA' } -+ end -+ -+ def test_ciphers_method_bogus_csuite -+ ssl_ctx = OpenSSL::SSL::SSLContext.new -+ -+ assert_raise_with_message( -+ OpenSSL::SSL::SSLError, -+ /SSL_CTX_set_cipher_list: no cipher match/i -+ ) { ssl_ctx.ciphers = 'BOGUS' } -+ end -+ - def test_connect_works_when_setting_dh_callback_to_nil - pend "TLS 1.2 is not supported" unless tls12_supported? - - ctx_proc = -> ctx { - ctx.ssl_version = :TLSv1_2 -diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb -index d696b98..4e2bd0c 100644 ---- a/test/openssl/test_x509cert.rb -+++ b/test/openssl/test_x509cert.rb -@@ -180,6 +180,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase - assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) }) - cert.serial = 2 - assert_equal(false, cert.verify(@rsa2048)) -+ rescue OpenSSL::X509::CertificateError # RHEL 9 disables SHA1 - end - - def test_sign_and_verify_rsa_md5 -@@ -226,9 +227,8 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase - assert_equal("dsa_with_SHA256", cert.signature_algorithm) - # TODO: need more tests for dsa + sha2 - -- # SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1) -- cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha1") -- assert_equal("dsaWithSHA1", cert.signature_algorithm) -+ cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha512") -+ assert_equal("dsa_with_SHA512", cert.signature_algorithm) - end - - def test_check_private_key -diff --git a/test/openssl/test_x509crl.rb b/test/openssl/test_x509crl.rb -index bcdb0a6..146ee07 100644 ---- a/test/openssl/test_x509crl.rb -+++ b/test/openssl/test_x509crl.rb -@@ -20,7 +20,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - - cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) - crl = issue_crl([], 1, now, now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_equal(1, crl.version) - assert_equal(cert.issuer.to_der, crl.issuer.to_der) - assert_equal(now, crl.last_update) -@@ -57,7 +57,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - ] - cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) - crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - revoked = crl.revoked - assert_equal(5, revoked.size) - assert_equal(1, revoked[0].serial) -@@ -98,7 +98,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - - revoke_info = (1..1000).collect{|i| [i, now, 0] } - crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - revoked = crl.revoked - assert_equal(1000, revoked.size) - assert_equal(1, revoked[0].serial) -@@ -124,7 +124,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - - cert = issue_cert(@ca, @rsa2048, 1, cert_exts, nil, nil) - crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts, -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - exts = crl.extensions - assert_equal(3, exts.size) - assert_equal("1", exts[0].value) -@@ -160,24 +160,24 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - assert_equal(false, exts[2].critical?) - - no_ext_crl = issue_crl([], 1, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_equal nil, no_ext_crl.authority_key_identifier - end - - def test_crlnumber - cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) - crl = issue_crl([], 1, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_match(1.to_s, crl.extensions[0].value) - assert_match(/X509v3 CRL Number:\s+#{1}/m, crl.to_text) - - crl = issue_crl([], 2**32, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_match((2**32).to_s, crl.extensions[0].value) - assert_match(/X509v3 CRL Number:\s+#{2**32}/m, crl.to_text) - - crl = issue_crl([], 2**100, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_match(/X509v3 CRL Number:\s+#{2**100}/m, crl.to_text) - assert_match((2**100).to_s, crl.extensions[0].value) - end -@@ -185,7 +185,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - def test_sign_and_verify - cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) - crl = issue_crl([], 1, Time.now, Time.now+1600, [], -- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - assert_equal(false, crl.verify(@rsa1024)) - assert_equal(true, crl.verify(@rsa2048)) - assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) }) -@@ -195,7 +195,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase - - cert = issue_cert(@ca, @dsa512, 1, [], nil, nil) - crl = issue_crl([], 1, Time.now, Time.now+1600, [], -- cert, @dsa512, OpenSSL::Digest.new('SHA1')) -+ cert, @dsa512, OpenSSL::Digest.new('SHA256')) - assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) }) - assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) }) - assert_equal(false, crl.verify(@dsa256)) -diff --git a/test/openssl/test_x509req.rb b/test/openssl/test_x509req.rb -index ee9c678..a84b162 100644 ---- a/test/openssl/test_x509req.rb -+++ b/test/openssl/test_x509req.rb -@@ -23,31 +23,31 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase - end - - def test_public_key -- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der) - -- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256')) - assert_equal(@dsa512.public_key.to_der, req.public_key.to_der) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(@dsa512.public_key.to_der, req.public_key.to_der) - end - - def test_version -- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(0, req.version) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(0, req.version) - -- req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(1, req.version) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(1, req.version) - end - - def test_subject -- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(@dn.to_der, req.subject.to_der) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(@dn.to_der, req.subject.to_der) -@@ -78,9 +78,9 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase - OpenSSL::X509::Attribute.new("msExtReq", attrval), - ] - -- req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - attrs.each{|attr| req0.add_attribute(attr) } -- req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - req1.attributes = attrs - assert_equal(req0.to_der, req1.to_der) - -@@ -101,7 +101,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase - end - - def test_sign_and_verify_rsa_sha1 -- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(true, req.verify(@rsa1024)) - assert_equal(false, req.verify(@rsa2048)) - assert_equal(false, request_error_returns_false { req.verify(@dsa256) }) -@@ -122,7 +122,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase - end - - def test_sign_and_verify_dsa -- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256')) - assert_equal(false, request_error_returns_false { req.verify(@rsa1024) }) - assert_equal(false, request_error_returns_false { req.verify(@rsa2048) }) - assert_equal(false, req.verify(@dsa256)) -@@ -137,13 +137,13 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase - end - - def test_dup -- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(req.to_der, req.dup.to_der) - end - - def test_eq -- req1 = issue_csr(0, @dn, @rsa1024, "sha1") -- req2 = issue_csr(0, @dn, @rsa1024, "sha1") -+ req1 = issue_csr(0, @dn, @rsa1024, "sha512") -+ req2 = issue_csr(0, @dn, @rsa1024, "sha512") - req3 = issue_csr(0, @dn, @rsa1024, "sha256") - - assert_equal false, req1 == 12345 ---- a/test/openssl/test_x509store.rb.orig 2022-07-14 14:07:32.468809273 +0200 -+++ b/test/openssl/test_x509store.rb 2022-07-13 17:27:58.115363595 +0200 -@@ -72,16 +72,16 @@ - - revoke_info = [] - crl1 = issue_crl(revoke_info, 1, now, now+1800, [], -- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - revoke_info = [ [2, now, 1], ] - crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [], -- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - revoke_info = [ [20, now, 1], ] - crl2 = issue_crl(revoke_info, 1, now, now+1800, [], -- ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA256')) - revoke_info = [] - crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [], -- ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA1')) -+ ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA256')) - - assert_equal(true, ca1_cert.verify(ca1_cert.public_key)) # self signed - assert_equal(true, ca2_cert.verify(ca1_cert.public_key)) # issued by ca1 -@@ -220,10 +220,10 @@ - - revoke_info = [] - crl1 = issue_crl(revoke_info, 1, now, now+1800, [], -- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - revoke_info = [ [2, now, 1], ] - crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [], -- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) -+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) - store.add_crl(crl1) - assert_raise(OpenSSL::X509::StoreError){ - store.add_crl(crl2) # add CRL issued by same CA twice. diff --git a/ruby.rpmlintrc b/ruby.rpmlintrc index bc72c06..f7d9d5a 100644 --- a/ruby.rpmlintrc +++ b/ruby.rpmlintrc @@ -12,45 +12,64 @@ addFilter(r'ruby\.(spec|src):\d+: W: unversioned-explicit-provides bundled\(ccan # The template files do not have to have executable bits. addFilter(r'^rubygem-bundler\.noarch: E: non-executable-script /usr/share/gems/gems/bundler-[\d\.]+/lib/bundler/templates/[\w/\.]+ 644 /usr/bin/env ') +# The template files can have /usr/bin/env +addFilter(r'^rubygem-bundler\.noarch: E: wrong-script-interpreter /usr/share/gems/gems/bundler-[\d\.]+/lib/bundler/templates/[\w/\.]+ /usr/bin/env ') + +# Just a test script. +addFilter(r'^rubygem-rss\.noarch: E: wrong-script-interpreter /usr/share/gems/gems/rss-[\d\.]+/test/[\w\-\.]+ /usr/bin/env ') # The bundled gem files permissions are overridden as 644 by `make install`. # https://bugs.ruby-lang.org/issues/17840 -# power_assert -# https://github.com/ruby/power_assert/issues/35 -addFilter(r'^rubygem-power_assert\.noarch: E: non-executable-script /usr/share/gems/gems/power_assert-[\d\.]+/bin/console 644 ') -addFilter(r'^rubygem-power_assert\.noarch: E: non-executable-script /usr/share/gems/gems/power_assert-[\d\.]+/bin/setup 644 ') -# rake -# https://github.com/ruby/rake/issues/385 -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/bundle 644 ') -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/console 644 ') -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/rake 644 ') -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/rdoc 644 ') -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/rubocop 644 ') -addFilter(r'^rubygem-rake\.noarch: E: non-executable-script /usr/share/gems/gems/rake-[\d\.]+/bin/setup 644 ') -# rbs -# https://github.com/ruby/rbs/issues/673 -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/annotate-with-rdoc 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/console 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/query-rdoc 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/rbs-prof 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/setup 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/sort 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/steep 644 ') -addFilter(r'^rubygem-rbs\.noarch: E: non-executable-script /usr/share/gems/gems/rbs-[\d\.]+/bin/test_runner.rb 644 ') -# test-unit -addFilter(r'^rubygem-test-unit\.noarch: E: non-executable-script /usr/share/gems/gems/test-unit-[\d\.]+/test/run-test.rb 644 ') +# https://github.com/rubygems/rubygems/issues/5255 +# https://github.com/ruby/debug/pull/481 +# https://github.com/ruby/net-ftp/pull/12 +# https://github.com/ruby/net-imap/pull/53 +# https://github.com/ruby/net-pop/pull/7 +# https://github.com/ruby/prime/pull/16 +addFilter(r'^.*: E: non-executable-script /usr/share/gems/gems/(debug|net-(ftp|imap|pop)|prime)-[\d\.]+/bin/\w+ 644 ') +addFilter(r'^.*: E: wrong-script-interpreter /usr/share/gems/gems/(debug|net-(ftp|imap|pop)|prime)-[\d\.]+/bin/\w+ /usr/bin/env') + +# Ruby provides API to set the cipher list. +addFilter(r'^ruby-libs\.\w+: W: crypto-policy-non-compliance-openssl /usr/lib(64)?/ruby/openssl.so SSL_CTX_set_cipher_list$') + +# `gethostbyname` is part of deprecated Ruby API. There is also request to drop the API altogether: +# https://bugs.ruby-lang.org/issues/13097 +# https://bugs.ruby-lang.org/issues/17944 +addFilter(r'^ruby-libs\.\w+: W: binary-or-shlib-calls-gethostbyname /usr/lib(64)?/ruby/socket.so$') + +# Nothing referred and no dependency information should be no problem. +# https://bugs.ruby-lang.org/issues/16558#note-2 +addFilter(r'^ruby-libs\.\w+: E: shared-library-without-dependency-information /usr/lib(64)?/ruby/enc/gb2312.so$') +# Compatibility for rpmlint 1.11. +addFilter(r'^ruby-libs\.\w+: E: shared-lib-without-dependency-information /usr/lib(64)?/ruby/enc/gb2312.so$') + +# These are Ruby plugins, where Ruby always load glibc prior the library. +addFilter(r'^ruby-libs\.\w+: W: library-not-linked-against-libc /usr/lib(64)?/ruby/.*.so$') # The function `chroot` without using `chdir` is detected by rpmlint with the # following message. However it looks a false positive as the `chroot` in the # `dir.c` is just used as a Ruby binding `Dir.chroot` for the function. # -# ruby-libs.x86_64: E: missing-call-to-chdir-with-chroot /usr/lib64/libruby.so.3.0.1 +# ruby-libs.x86_64: E: missing-call-to-chdir-with-chroot /usr/lib64/libruby.so.N.N.N # This executable appears to call chroot without using chdir to change the # current directory. This is likely an error and permits an attacker to break # out of the chroot by using fchdir. While that's not always a security issue, # this has to be checked. addFilter(r'^ruby-libs\.\w+: E: missing-call-to-chdir-with-chroot /usr/lib(64)?/libruby.so.[\d/.]+$') -# Nothing referred and no dependency information should be no problem. -# https://bugs.ruby-lang.org/issues/16558#note-2 -addFilter(r'^ruby-libs\.\w+: E: shared-lib-without-dependency-information /usr/lib(64)?/ruby/enc/gb2312.so$') +# Rake ships some examples. +addFilter(r'^rubygem-rake.noarch: W: devel-file-in-non-devel-package /usr/share/gems/gems/rake-[\d\.]+/doc/example/\w+.c$') + +# Some executables don't have their manual pages. Is it worth of use help2man? +addFilter(r'^.+: W: no-manual-page-for-binary (bundler|gem|rbs|rdbg|rdoc|ruby-mri|typeprof)$') + +# Default gems does not come with any documentation. +addFilter(r'^rubygem-(bigdecimal|io-console|json|psych)\.\w+: W: no-documentation$') + +# rubygems-devel ships only RPM macros and generators. Their placement is given +# by RPM and can't be modified. +addFilter(r'rubygems-devel.noarch: W: only-non-binary-in-usr-lib$') + +# The empty gem.build_complete file is false positive. This error is gone in rpmlint 2.0+. +# https://github.com/rpm-software-management/rpmlint/commit/e34ce874f27d733628f51c9884ac951af072bed2 +addFilter(r'^ruby(gem)?-(bigdecimal|bundled-gems|io-console|json|psych|rbs)\.\w+: E: zero-length /usr/lib(64)?/gems/ruby/.*/gem.build_complete') diff --git a/rubygems-3.2.30-Provide-distinguished-name-which-will-be-correctly-p.patch b/rubygems-3.2.30-Provide-distinguished-name-which-will-be-correctly-p.patch deleted file mode 100644 index 433d03e..0000000 --- a/rubygems-3.2.30-Provide-distinguished-name-which-will-be-correctly-p.patch +++ /dev/null @@ -1,44 +0,0 @@ -From bb0f57aeb4de36a3b2b8b8cb01d25b32af0357d3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?V=C3=ADt=20Ondruch?= -Date: Wed, 27 Oct 2021 16:28:24 +0200 -Subject: [PATCH] Provide distinguished name which will be correctly parsed. - -It seems that since ruby openssl 2.1.0 [[1]], the distinguished name -submitted to `OpenSSL::X509::Name.parse` is not correctly parsed if it -does not contain the first slash: - -~~~ -$ ruby -v -ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] - -$ gem list | grep openssl -openssl (default: 2.2.0) - -$ irb -r openssl -irb(main):001:0> OpenSSL::X509::Name.parse("CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE) -=> "CN = nobody/DC=example" -irb(main):002:0> OpenSSL::X509::Name.parse("/CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE) -=> "CN = nobody, DC = example" -~~~ - -[1]: https://github.com/ruby/openssl/commit/19c67cd10c57f3ab7b13966c36431ebc3fdd653b ---- - lib/rubygems/security.rb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb -index c80639af6d..12de141f36 100644 ---- a/lib/rubygems/security.rb -+++ b/lib/rubygems/security.rb -@@ -510,7 +510,7 @@ def self.email_to_name(email_address) - - dcs = dcs.split '.' - -- name = "CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}" -+ name = "/CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}" - - OpenSSL::X509::Name.parse name - end --- -2.32.0 - diff --git a/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch b/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch deleted file mode 100644 index d5a0673..0000000 --- a/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch +++ /dev/null @@ -1,261 +0,0 @@ -From e80e7a3d0b3d72f7af7286b935702b3fab117008 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Rodr=C3=ADguez?= -Date: Wed, 8 Dec 2021 21:12:24 +0100 -Subject: [PATCH 1/5] More explicit require - -This class does not use `rubygems/deprecate`. It uses -`rubygems/version`, which in turn uses `rubygems/deprecate`. Make this -explicit. ---- - lib/rubygems/requirement.rb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb -index d2e28fab5b4..9edd6aa7d3c 100644 ---- a/lib/rubygems/requirement.rb -+++ b/lib/rubygems/requirement.rb -@@ -1,5 +1,5 @@ - # frozen_string_literal: true --require_relative "deprecate" -+require_relative "version" - - ## - # A Requirement is a set of one or more version restrictions. It supports a - -From 4e46dcc17ee5cabbde43b8a34063b8ab042536f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Rodr=C3=ADguez?= -Date: Wed, 8 Dec 2021 21:17:30 +0100 -Subject: [PATCH 2/5] Remove ineffective autoloads - -These files are loaded on startup unconditionally, so we can require -them relatively when needed. ---- - lib/rubygems.rb | 4 +--- - lib/rubygems/specification.rb | 2 ++ - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/rubygems.rb b/lib/rubygems.rb -index f803e47628e..b8747409304 100644 ---- a/lib/rubygems.rb -+++ b/lib/rubygems.rb -@@ -1310,19 +1310,17 @@ def default_gem_load_paths - autoload :Licenses, File.expand_path('rubygems/util/licenses', __dir__) - autoload :NameTuple, File.expand_path('rubygems/name_tuple', __dir__) - autoload :PathSupport, File.expand_path('rubygems/path_support', __dir__) -- autoload :Platform, File.expand_path('rubygems/platform', __dir__) - autoload :RequestSet, File.expand_path('rubygems/request_set', __dir__) -- autoload :Requirement, File.expand_path('rubygems/requirement', __dir__) - autoload :Resolver, File.expand_path('rubygems/resolver', __dir__) - autoload :Source, File.expand_path('rubygems/source', __dir__) - autoload :SourceList, File.expand_path('rubygems/source_list', __dir__) - autoload :SpecFetcher, File.expand_path('rubygems/spec_fetcher', __dir__) -- autoload :Specification, File.expand_path('rubygems/specification', __dir__) - autoload :Util, File.expand_path('rubygems/util', __dir__) - autoload :Version, File.expand_path('rubygems/version', __dir__) - end - - require_relative 'rubygems/exceptions' -+require_relative 'rubygems/specification' - - # REFACTOR: This should be pulled out into some kind of hacks file. - begin -diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb -index d3b96491a28..dc5e5ba0138 100644 ---- a/lib/rubygems/specification.rb -+++ b/lib/rubygems/specification.rb -@@ -9,6 +9,8 @@ - require_relative 'deprecate' - require_relative 'basic_specification' - require_relative 'stub_specification' -+require_relative 'platform' -+require_relative 'requirement' - require_relative 'specification_policy' - require_relative 'util/list' - - -From 96b6b3e04e8e4fec17f63079a0caf999a2709d71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Rodr=C3=ADguez?= -Date: Wed, 8 Dec 2021 21:45:16 +0100 -Subject: [PATCH 3/5] Load `operating_system.rb` customizations before setting - up default gems - -It's very common for packagers to configure gem paths in this file, for -example, `Gem.default_dir`. Also, setting up default gems requires these -paths to be set, so that we know which default gems need to be setup. - -If we setup default gems before loading `operatin_system.rb` -customizations, the wrong default gems will be setup. - -Unfortunately, default gems loaded by `operating_system.rb` can't be -upgraded if we do this, but it seems much of a smaller issue. I wasn't -even fully sure it was the right thing to do when I added that, and it -was not the culprit of the end user issue that led to making that -change. ---- - lib/rubygems.rb | 32 ++++++++++++++++---------------- - test/rubygems/test_rubygems.rb | 23 +++++++++++++++++++++++ - 2 files changed, 39 insertions(+), 16 deletions(-) - -diff --git a/lib/rubygems.rb b/lib/rubygems.rb -index b8747409304..11474b6554c 100644 ---- a/lib/rubygems.rb -+++ b/lib/rubygems.rb -@@ -1323,22 +1323,6 @@ def default_gem_load_paths - require_relative 'rubygems/specification' - - # REFACTOR: This should be pulled out into some kind of hacks file. --begin -- ## -- # Defaults the Ruby implementation wants to provide for RubyGems -- -- require "rubygems/defaults/#{RUBY_ENGINE}" --rescue LoadError --end -- --## --# Loads the default specs. --Gem::Specification.load_defaults -- --require_relative 'rubygems/core_ext/kernel_gem' --require_relative 'rubygems/core_ext/kernel_require' --require_relative 'rubygems/core_ext/kernel_warn' -- - begin - ## - # Defaults the operating system (or packager) wants to provide for RubyGems. -@@ -1354,3 +1338,19 @@ def default_gem_load_paths - "the problem and ask for help." - raise e.class, msg - end -+ -+begin -+ ## -+ # Defaults the Ruby implementation wants to provide for RubyGems -+ -+ require "rubygems/defaults/#{RUBY_ENGINE}" -+rescue LoadError -+end -+ -+## -+# Loads the default specs. -+Gem::Specification.load_defaults -+ -+require_relative 'rubygems/core_ext/kernel_gem' -+require_relative 'rubygems/core_ext/kernel_require' -+require_relative 'rubygems/core_ext/kernel_warn' -diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb -index 493b9fdf4a3..fa77a299322 100644 ---- a/test/rubygems/test_rubygems.rb -+++ b/test/rubygems/test_rubygems.rb -@@ -22,6 +22,29 @@ def test_operating_system_other_exceptions - "the problem and ask for help." - end - -+ def test_operating_system_customizing_default_dir -+ pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby' -+ pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby' -+ -+ # On a non existing default dir, there should be no gems -+ -+ path = util_install_operating_system_rb <<-RUBY -+ module Gem -+ def self.default_dir -+ File.expand_path("foo") -+ end -+ end -+ RUBY -+ -+ output = Gem::Util.popen( -+ *ruby_with_rubygems_and_fake_operating_system_in_load_path(path), -+ '-e', -+ "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)", -+ {:err => [:child, :out]} -+ ).strip -+ assert_empty output -+ end -+ - private - - def util_install_operating_system_rb(content) - -From 52cfdd14fd1213a97aac12f01177e27779de9035 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Rodr=C3=ADguez?= -Date: Thu, 9 Dec 2021 06:08:31 +0100 -Subject: [PATCH 4/5] Install default fiddle on latest ruby on specs that need - it - -Otherwise first OS customizations load and activate that fiddle version, -but then when we change to `Gem.default_dir`, that fiddle version is no -longer there. ---- - spec/bundler/commands/clean_spec.rb | 2 +- - spec/bundler/install/gems/standalone_spec.rb | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb -index ffaf22dbb32..65231b35fac 100644 ---- a/spec/bundler/commands/clean_spec.rb -+++ b/spec/bundler/commands/clean_spec.rb -@@ -638,7 +638,7 @@ def should_not_have_gems(*gems) - s.executables = "irb" - end - -- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1" -+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1" - - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" -diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb -index db16a1b0e13..faefda25f45 100644 ---- a/spec/bundler/install/gems/standalone_spec.rb -+++ b/spec/bundler/install/gems/standalone_spec.rb -@@ -113,7 +113,7 @@ - skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2 - skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0" - -- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0" -+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0" - - necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"] - necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a") - -From c6a9c81021092c9157f5616a2bbe1323411a5bf8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Rodr=C3=ADguez?= -Date: Thu, 9 Dec 2021 12:46:23 +0100 -Subject: [PATCH 5/5] Resolve symlinks in LOAD_PATH when activating - pre-required default gems - -Some double load issues were reported a while ago by OS packagers where -if a gem has been required before rubygems, and then after, rubygems -require would cause a double load. - -We avoid this issue by activating the corresponding gem if we detect -that a file in the default LOAD_PATH that belongs to a default gem has -already been required when rubygems registers default gems. - -However, the fix does not take into account that the default LOAD_PATH -could potentially include symlinks. This change fixes the same double -load issue described above but for situations where the default -LOAD_PATH includes symlinks. ---- - lib/rubygems.rb | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/lib/rubygems.rb b/lib/rubygems.rb -index 11474b6554c..b7dda38d522 100644 ---- a/lib/rubygems.rb -+++ b/lib/rubygems.rb -@@ -1293,7 +1293,12 @@ def already_loaded?(file) - end - - def default_gem_load_paths -- @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1] -+ @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp| -+ expanded = File.expand_path(lp) -+ next expanded unless File.exist?(expanded) -+ -+ File.realpath(expanded) -+ end - end - end - diff --git a/rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch b/rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch deleted file mode 100644 index b405b5f..0000000 --- a/rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 558128594de16add5b453833fd5b043a24c1b7f5 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 22 Dec 2021 01:38:47 +0900 -Subject: [PATCH 1/3] Use OpenSSL::PKey::EC.generate to generate ECC key pairs - -When Ruby/OpenSSL is built against OpenSSL 3.0, OpenSSL::PKey::PKey -instances are immutable and OpenSSL::PKey::EC#generate_key cannot work -because it modifies the receiver. - -OpenSSL::PKey::EC.generate is available on Ruby 2.4 (Ruby/OpenSSL 2.0) -or later. ---- - lib/rubygems/security.rb | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb -index 22759972070..2aa07381d69 100644 ---- a/lib/rubygems/security.rb -+++ b/lib/rubygems/security.rb -@@ -490,9 +490,13 @@ def self.create_key(algorithm) - when 'rsa' - OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH) - when 'ec' -- domain_key = OpenSSL::PKey::EC.new(EC_NAME) -- domain_key.generate_key -- domain_key -+ if RUBY_VERSION >= "2.4.0" -+ OpenSSL::PKey::EC.generate(EC_NAME) -+ else -+ domain_key = OpenSSL::PKey::EC.new(EC_NAME) -+ domain_key.generate_key -+ domain_key -+ end - else - raise Gem::Security::Exception, - "#{algorithm} algorithm not found. RSA, DSA, and EC algorithms are supported." - -From 60067d4f09b7fb9c23bed38e91acfde0293f29a0 Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 22 Dec 2021 01:49:05 +0900 -Subject: [PATCH 2/3] Use OpenSSL::X509::Certificate#check_private_key - -The method is for the exact purpose: to check that an instance of -OpenSSL::PKey::PKey matches the public key in a certificate. ---- - lib/rubygems/security.rb | 2 +- - lib/rubygems/security/policy.rb | 4 +--- - 2 files changed, 2 insertions(+), 4 deletions(-) - -diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb -index 2aa07381d69..2906819bd34 100644 ---- a/lib/rubygems/security.rb -+++ b/lib/rubygems/security.rb -@@ -530,7 +530,7 @@ def self.re_sign(expired_certificate, private_key, age = ONE_YEAR, - raise Gem::Security::Exception, - "incorrect signing key for re-signing " + - "#{expired_certificate.subject}" unless -- expired_certificate.public_key.to_pem == get_public_key(private_key).to_pem -+ expired_certificate.check_private_key(private_key) - - unless expired_certificate.subject.to_s == - expired_certificate.issuer.to_s -diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb -index 3c3cb647ee3..06eae073f4a 100644 ---- a/lib/rubygems/security/policy.rb -+++ b/lib/rubygems/security/policy.rb -@@ -115,11 +115,9 @@ def check_key(signer, key) - raise Gem::Security::Exception, 'missing key or signature' - end - -- public_key = Gem::Security.get_public_key(key) -- - raise Gem::Security::Exception, - "certificate #{signer.subject} does not match the signing key" unless -- signer.public_key.to_pem == public_key.to_pem -+ signer.check_private_key(key) - - true - end - -From 6819e3d0fadc10ce8d10919402eedb730cf0e43f Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi -Date: Wed, 22 Dec 2021 01:54:10 +0900 -Subject: [PATCH 3/3] Fix Gem::Security.get_public_key on OpenSSL 3.0 - -Ruby/OpenSSL 2.2 added OpenSSL::PKey::PKey#public_to_der for serializing -only the public key components contained in the instance. This works -for all possible key types. ---- - lib/rubygems/security.rb | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb -index 2906819bd34..f21c1756422 100644 ---- a/lib/rubygems/security.rb -+++ b/lib/rubygems/security.rb -@@ -424,6 +424,8 @@ def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, - # Gets the right public key from a PKey instance - - def self.get_public_key(key) -+ # Ruby 3.0 (Ruby/OpenSSL 2.2) or later -+ return OpenSSL::PKey.read(key.public_to_der) if key.respond_to?(:public_to_der) - return key.public_key unless key.is_a?(OpenSSL::PKey::EC) - - ec_key = OpenSSL::PKey::EC.new(key.group.curve_name)