From 5315832a205e9d408d76368a2aaace72ebeb8545 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 10 Apr 2024 16:56:03 +0200 Subject: [PATCH] [fix] make sure PKeyEC#group.curve_name is always set --- .../java/org/jruby/ext/openssl/PKeyEC.java | 36 +++++++++++-------- src/test/ruby/test_pkey.rb | 4 +++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/jruby/ext/openssl/PKeyEC.java b/src/main/java/org/jruby/ext/openssl/PKeyEC.java index 9fc1f923..3075723f 100644 --- a/src/main/java/org/jruby/ext/openssl/PKeyEC.java +++ b/src/main/java/org/jruby/ext/openssl/PKeyEC.java @@ -202,6 +202,7 @@ public PKeyEC(Ruby runtime, RubyClass type) { setPrivateKey((ECPrivateKey) privKey); } else { this.privateKey = privKey; + setCurveNameFromPublicKeyIfNeeded(); } } @@ -353,14 +354,18 @@ else if ( key instanceof ECPublicKey ) { throw newECError(runtime, "Neither PUB key nor PRIV key: "); } - if ( curveName == null && publicKey != null ) { - final String oid = getCurveNameObjectIdFromKey(context, publicKey); + setCurveNameFromPublicKeyIfNeeded(); + + return this; + } + + private void setCurveNameFromPublicKeyIfNeeded() { + if (curveName == null && publicKey != null) { + final String oid = getCurveNameObjectIdFromKey(getRuntime(), publicKey); if (isCurveName(oid)) { this.curveName = getCurveName(new ASN1ObjectIdentifier(oid)); } } - - return this; } void setPrivateKey(final ECPrivateKey key) { @@ -376,17 +381,17 @@ private void unwrapPrivateKeyWithName() { } } - private static String getCurveNameObjectIdFromKey(final ThreadContext context, final ECPublicKey key) { + private static String getCurveNameObjectIdFromKey(final Ruby runtime, final ECPublicKey key) { try { AlgorithmParameters algParams = AlgorithmParameters.getInstance("EC"); algParams.init(key.getParams()); return algParams.getParameterSpec(ECGenParameterSpec.class).getName(); } catch (NoSuchAlgorithmException|InvalidParameterSpecException ex) { - throw newECError(context.runtime, ex.getMessage()); + throw newECError(runtime, ex.getMessage()); } catch (Exception ex) { - throw (RaiseException) newECError(context.runtime, ex.toString()).initCause(ex); + throw (RaiseException) newECError(runtime, ex.toString()).initCause(ex); } } @@ -535,10 +540,7 @@ public IRubyObject oid() { private Group getGroup(boolean required) { if (group == null) { - if (publicKey != null) { - return group = new Group(getRuntime(), this); - } - if (required) throw new IllegalStateException("no group (without public key)"); + return group = new Group(getRuntime(), this); } return group; } @@ -748,7 +750,6 @@ public Group(Ruby runtime, RubyClass type) { Group(Ruby runtime, PKeyEC key) { this(runtime, _EC(runtime).getClass("Group")); this.key = key; - this.paramSpec = key.publicKey.getParams(); } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) @@ -759,8 +760,7 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject[] a IRubyObject arg = args[0]; if ( arg instanceof Group ) { - IRubyObject curve_name = ((Group) arg).curve_name(context); - this.curve_name = curve_name.isNil() ? null : (RubyString) curve_name; + this.curve_name = ((Group) arg).implCurveName(runtime); return this; } @@ -771,6 +771,7 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject[] a private String getCurveName() { if (key != null) return key.getCurveName(); + assert curve_name != null; return curve_name.toString(); } @@ -792,6 +793,7 @@ public IRubyObject curve_name(final ThreadContext context) { private RubyString implCurveName(final Ruby runtime) { if (curve_name == null) { + assert key != null; String prefix, curveName = key.getCurveName(); // BC 1.54: "brainpoolP512t1" 1.55: "brainpoolp512t1" if (curveName.startsWith(prefix = "brainpoolp")) { @@ -854,7 +856,11 @@ public RubyString to_pem(final ThreadContext context, final IRubyObject[] args) private ECParameterSpec getParamSpec() { if (paramSpec == null) { - paramSpec = PKeyEC.getParamSpec(getCurveName()); + if (key != null) { + return paramSpec = key.getParamSpec(); + } + assert curve_name != null; + return paramSpec = PKeyEC.getParamSpec(getCurveName()); } return paramSpec; } diff --git a/src/test/ruby/test_pkey.rb b/src/test/ruby/test_pkey.rb index 523199dc..30b83489 100644 --- a/src/test/ruby/test_pkey.rb +++ b/src/test/ruby/test_pkey.rb @@ -24,6 +24,7 @@ def test_read_files key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256k-private.pem'))) assert_equal OpenSSL::PKey::EC, key.class assert key.private_key? + assert_equal 'secp256k1', key.group.curve_name key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256k-public.pem'))) assert_equal OpenSSL::PKey::EC, key.class @@ -32,14 +33,17 @@ def test_read_files key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256-public-v2.pem'))) assert_equal OpenSSL::PKey::EC, key.class assert key.public_key? + assert_equal 'prime256v1', key.group.curve_name key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec512-private.pem'))) assert_equal OpenSSL::PKey::EC, key.class assert key.private_key? + assert_equal 'secp521r1', key.group.curve_name key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec512-public.pem'))) assert_equal OpenSSL::PKey::EC, key.class assert key.public_key? + assert_equal 'secp521r1', key.group.curve_name key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'rsa-2048-private.pem'))) assert_equal OpenSSL::PKey::RSA, key.class