Skip to content

Commit f67c0af

Browse files
committed
[compat] add PKey::EC#derive and fix nil group
1 parent 23b1cef commit f67c0af

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/main/java/org/jruby/ext/openssl/PKeyEC.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,20 @@ public IRubyObject dh_compute_key(final ThreadContext context, final IRubyObject
597597
}
598598
}
599599

600+
// derive(peer_key) -- computes the ECDH shared secret with a peer EC public key.
601+
// Equivalent to dh_compute_key(peer_key.public_key).
602+
@JRubyMethod(name = "derive")
603+
public IRubyObject derive(final ThreadContext context, final IRubyObject peer) {
604+
if (!(peer instanceof PKeyEC)) {
605+
throw context.runtime.newTypeError(peer, _EC(context.runtime));
606+
}
607+
final IRubyObject peerPublicKey = ((PKeyEC) peer).public_key(context);
608+
if (peerPublicKey.isNil()) {
609+
throw newECError(context.runtime, "no public key");
610+
}
611+
return dh_compute_key(context, peerPublicKey);
612+
}
613+
600614
@JRubyMethod
601615
public IRubyObject oid() {
602616
return getRuntime().newString("id-ecPublicKey");
@@ -617,8 +631,8 @@ public IRubyObject group(ThreadContext context) {
617631
Group group = this.group;
618632
if (group != null) return group;
619633

620-
if (publicKey == null && publicKey == null) {
621-
return context.nil; // PKey::EC.new
634+
if (getCurveName() == null) {
635+
return context.nil; // PKey::EC.new with no args / no curve configured
622636
}
623637
group = getGroup(false);
624638
return group == null ? context.nil : group;

src/test/ruby/ec/test_ec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,24 @@ def test_sign_verify
432432
assert_equal false, p256.verify("SHA256", signature1, data)
433433
end
434434

435+
def test_derive_key
436+
# NIST CAVP, KAS_ECC_CDH_PrimitiveTest.txt, P-256 COUNT = 0
437+
qCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287"
438+
qCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"
439+
dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"
440+
zIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b"
441+
442+
a = OpenSSL::PKey::EC.new("prime256v1")
443+
a.private_key = OpenSSL::BN.new(dIUT, 16)
444+
445+
b = OpenSSL::PKey::EC.new("prime256v1")
446+
uncompressed = OpenSSL::BN.new("04" + qCAVSx + qCAVSy, 16)
447+
b.public_key = OpenSSL::PKey::EC::Point.new(b.group, uncompressed)
448+
449+
assert_equal [zIUT].pack("H*"), a.derive(b)
450+
assert_equal a.derive(b), a.dh_compute_key(b.public_key)
451+
end
452+
435453
def test_ec_group
436454
group1 = OpenSSL::PKey::EC::Group.new("prime256v1")
437455
key1 = OpenSSL::PKey::EC.new(group1)

0 commit comments

Comments
 (0)