From c34c8824af15905b60c6cde468d1dc07371cd291 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 27 Feb 2026 16:41:01 -0600 Subject: [PATCH 1/4] Fully drop 9.1 support JRuby API signatures that do not pass ThreadContext are starting to be removed in JRuby 10.1, and the context versions do not exist until 9.2. JRuby 9.1 is also nearly a decade old and has been EOL for at least half as long. --- Mavenfile | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mavenfile b/Mavenfile index 5da58239..3330d25f 100644 --- a/Mavenfile +++ b/Mavenfile @@ -82,14 +82,14 @@ plugin :clean do 'failOnError' => 'false' ) end -jar 'org.jruby:jruby-core', '9.1.11.0', :scope => :provided +jar 'org.jruby:jruby-core', '9.2.19.0', :scope => :provided # for invoker generated classes we need to add javax.annotation when on Java > 8 jar 'javax.annotation:javax.annotation-api', '1.3.1', :scope => :compile jar 'junit:junit', '[4.13.1,)', :scope => :test # NOTE: to build on Java 11 - installing gems fails (due old jossl) with: # load error: jopenssl/load -- java.lang.StringIndexOutOfBoundsException -MVN_JRUBY_VERSION = ENV_JAVA['java.version'].to_i >= 9 ? '9.2.19.0' : '9.1.17.0' +MVN_JRUBY_VERSION = '9.2.19.0' jruby_plugin! :gem do # when installing dependent gems we want to use the built in openssl not the one from this lib directory diff --git a/pom.xml b/pom.xml index 4b1795b9..f9e72d28 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ DO NOT MODIFY - GENERATED CODE org.jruby jruby-core - 9.1.11.0 + 9.2.19.0 provided From 829212d5ee443ecadbc64e4588c946b3564e766b Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 27 Feb 2026 16:36:09 -0600 Subject: [PATCH 2/4] Digest can be passed in as a String --- src/main/java/org/jruby/ext/openssl/Digest.java | 9 +++++++++ src/main/java/org/jruby/ext/openssl/X509Request.java | 7 ++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jruby/ext/openssl/Digest.java b/src/main/java/org/jruby/ext/openssl/Digest.java index 76f50377..e8b72cb4 100644 --- a/src/main/java/org/jruby/ext/openssl/Digest.java +++ b/src/main/java/org/jruby/ext/openssl/Digest.java @@ -124,6 +124,15 @@ static MessageDigest getDigest(final Ruby runtime, final String name) { } } + static Digest getDigest(ThreadContext context, IRubyObject digest) { + if (digest instanceof Digest) { + return (Digest) digest; + } else { + RubyString digestString = digest.convertToString(); + return newInstance(context.runtime, digestString, context.nil); + } + } + private static Digest newInstance(final Ruby runtime, final IRubyObject name, final IRubyObject data) { final RubyClass klass = _Digest(runtime); final Digest instance = new Digest(runtime, klass); diff --git a/src/main/java/org/jruby/ext/openssl/X509Request.java b/src/main/java/org/jruby/ext/openssl/X509Request.java index 7947f38f..62938afc 100644 --- a/src/main/java/org/jruby/ext/openssl/X509Request.java +++ b/src/main/java/org/jruby/ext/openssl/X509Request.java @@ -296,13 +296,14 @@ public IRubyObject set_public_key(final IRubyObject pkey) { @JRubyMethod public IRubyObject sign(final ThreadContext context, - final IRubyObject key, final IRubyObject digest) { + final IRubyObject key, final IRubyObject _digest) { PrivateKey privateKey = ((PKey) key).getPrivateKey(); + Digest digest = Digest.getDigest(context, _digest); final Ruby runtime = context.runtime; - supportedSignatureAlgorithm(runtime, _RequestError(runtime), public_key, (Digest) digest); + supportedSignatureAlgorithm(runtime, _RequestError(runtime), public_key, digest); - final String digAlg = ((Digest) digest).getShortAlgorithm(); + final String digAlg = digest.getShortAlgorithm(); try { request = null; getRequest().sign( privateKey, digAlg ); From 196bc9d3d71172f906789afdf225e18bb3a46f14 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 27 Feb 2026 16:36:22 -0600 Subject: [PATCH 3/4] Switch to undeprecated default_value_set The context version replaces the old deprecated signature without context, and that version will be removed in JRuby 10.1. --- src/main/java/org/jruby/ext/openssl/X509Name.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jruby/ext/openssl/X509Name.java b/src/main/java/org/jruby/ext/openssl/X509Name.java index 58b6a4e4..1d7f8b58 100644 --- a/src/main/java/org/jruby/ext/openssl/X509Name.java +++ b/src/main/java/org/jruby/ext/openssl/X509Name.java @@ -123,7 +123,8 @@ static void createX509Name(final Ruby runtime, final RubyModule X509, final Ruby final RubyFixnum IA5_STRING = runtime.newFixnum(BERTags.IA5_STRING); final ThreadContext context = runtime.getCurrentContext(); - final RubyHash hash = new RubyHash(runtime, UTF8_STRING); + final RubyHash hash = RubyHash.newHash(runtime); + hash.default_value_set(context, UTF8_STRING); hash.op_aset(context, newString(runtime, new byte[] { 'C' }), PRINTABLE_STRING); final byte[] countryName = { 'c','o','u','n','t','r','y','N','a','m','e' }; hash.op_aset(context, newString(runtime, countryName), PRINTABLE_STRING); From 3b7d8cbff3fdc2c79c1f8a00a292970abc52a221 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 27 Feb 2026 18:11:47 -0600 Subject: [PATCH 4/4] Try to match MRI error conditions for PKey::EC --- src/main/java/org/jruby/ext/openssl/PKeyEC.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/jruby/ext/openssl/PKeyEC.java b/src/main/java/org/jruby/ext/openssl/PKeyEC.java index e698e425..9dcd6a58 100644 --- a/src/main/java/org/jruby/ext/openssl/PKeyEC.java +++ b/src/main/java/org/jruby/ext/openssl/PKeyEC.java @@ -13,6 +13,7 @@ import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; +import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; @@ -438,6 +439,9 @@ public PKeyEC generate_key(final ThreadContext context) { this.publicKey = (ECPublicKey) pair.getPublic(); this.privateKey = pair.getPrivate(); } + catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException ex) { + throw newPKeyError(context.runtime, ex.getMessage()); + } catch (GeneralSecurityException ex) { throw newECError(context.runtime, ex.toString()); } @@ -558,6 +562,9 @@ public IRubyObject oid() { private Group getGroup(boolean required) { if (group == null) { + if (curveName == null) { + return null; + } return group = new Group(getRuntime(), this); } return group; @@ -857,6 +864,11 @@ public Group(Ruby runtime, RubyClass type) { setCurveName(runtime, key.getCurveName()); } + private static RaiseException newError(final Ruby runtime, final String message) { + final RubyClass Error = _EC(runtime).getClass("Group").getClass("Error"); + return Utils.newError(runtime, Error, message); + } + @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; @@ -967,6 +979,9 @@ public RubyString to_pem(final ThreadContext context, final IRubyObject[] args) } private ECParameterSpec getParamSpec() { + if (curveName == null) { + throw newError(getRuntime(), "unsupported field: curveName is null"); + } if (paramSpec == null) { paramSpec = PKeyEC.getParamSpec(getCurveName()); }