Skip to content

Commit

Permalink
[fix] make sure PKeyEC#group.curve_name is always set
Browse files Browse the repository at this point in the history
  • Loading branch information
kares committed Apr 10, 2024
1 parent 6af9858 commit 5315832
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 15 deletions.
36 changes: 21 additions & 15 deletions src/main/java/org/jruby/ext/openssl/PKeyEC.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public PKeyEC(Ruby runtime, RubyClass type) {
setPrivateKey((ECPrivateKey) privKey);
} else {
this.privateKey = privKey;
setCurveNameFromPublicKeyIfNeeded();
}
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}

Expand All @@ -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();
}

Expand All @@ -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")) {
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/ruby/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 5315832

Please sign in to comment.