Skip to content

Commit d9dc3f0

Browse files
committed
[feat] support to_java protocol for PKey (#250)
1 parent c34395f commit d9dc3f0

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,25 @@ public ASN1Primitive toASN1PublicInfo() throws IOException {
237237
return data;
238238
}
239239

240+
@Override
241+
public Object toJava(final Class target) {
242+
if (PrivateKey.class.isAssignableFrom(target)) {
243+
final PrivateKey key = getPrivateKey();
244+
if (key == null) {
245+
throw getRuntime().newRuntimeError("private key not available, to convert to " + target);
246+
}
247+
if (target.isInstance(key)) return key;
248+
throw getRuntime().newTypeError("cannot convert private key of type " + key.getClass() + " to " + target);
249+
}
250+
if (target.isAssignableFrom(PublicKey.class) || Key.class.isAssignableFrom(target)) {
251+
// default is public key, also want to_java() as well as to_java(java.lang.Object) to end up here
252+
final PublicKey key = getPublicKey();
253+
if (target.isInstance(key)) return key;
254+
throw getRuntime().newTypeError("cannot convert public key of type " + key.getClass() + " to " + target);
255+
}
256+
return super.toJava(target);
257+
}
258+
240259
static ByteList sign(final String signAlg, final PrivateKey privateKey, final ByteList data)
241260
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
242261
Signature signature = SecurityHelper.getSignature(signAlg);

src/test/ruby/rsa/test_rsa.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,22 @@ def test_RSAPublicKey
179179
assert_equal expected, OpenSSL::Digest::SHA1.hexdigest(key.to_der)
180180
end if !defined?(JRUBY_VERSION) || JRUBY_VERSION > '9.1' # set_key only since Ruby 2.3
181181

182+
def test_to_java
183+
key_file = File.join(File.dirname(__FILE__), 'private_key.pem')
184+
pkey = OpenSSL::PKey::RSA.new(File.read(key_file))
185+
assert_kind_of java.security.PublicKey, pkey.to_java
186+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.PublicKey)
187+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.interfaces.RSAPublicKey)
188+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.Key)
189+
assert_kind_of java.security.PrivateKey, pkey.to_java(java.security.PrivateKey)
190+
assert_kind_of java.security.PrivateKey, pkey.to_java(java.security.interfaces.RSAPrivateKey)
191+
priv_key = pkey.to_java(java.security.PrivateKey)
192+
if priv_key.is_a? org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
193+
assert_kind_of java.security.PrivateKey, pkey.to_java(org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey)
194+
end
195+
assert_raise_kind_of(TypeError) { pkey.to_java(java.security.interfaces.ECPrivateKey) }
196+
end if defined?(JRUBY_VERSION)
197+
182198
private
183199

184200
def assert_same_rsa(expected, key)

src/test/ruby/test_pkey.rb

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,30 @@
33

44
class TestPKey < TestCase
55

6-
def test_pkey_read
7-
key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArTlm5TxJp3WHMNmWIfo/\nWvkyhJCXc1S78Y9B8lSXxXnkRqX8Twxu5EkdUP0TwgD5gp0TGy7UPm/SgWlQOcqX\nqtdOWq/Hk29Ve9z6k6wTmst7NTefmm/7OqkeYmBhfhoECLCKBADM8ctjoqD63R0e\n3bUW2knq6vCS5YMmD76/5UoU647BzB9CjgDzjuTKEbXL5AvcO5wWDgHSp7CA+2t4\nIFQvQMrPso5mvm2hNvD19vI0VjiY21rKgkJQAXSrLgkJg/fTL2wQiz10d2GnYsmx\nDeJCiBMwC+cmRW2eWePqaCPaWJwr92KsIiry+LgyGb3y01SUVV8kQgQXazutHqfu\ncQIDAQAB\n-----END PUBLIC KEY-----\n"
8-
9-
# assert OpenSSL::PKey::RSA.new(key).public?
6+
KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArTlm5TxJp3WHMNmWIfo/\nWvkyhJCXc1S78Y9B8lSXxXnkRqX8Twxu5EkdUP0TwgD5gp0TGy7UPm/SgWlQOcqX\nqtdOWq/Hk29Ve9z6k6wTmst7NTefmm/7OqkeYmBhfhoECLCKBADM8ctjoqD63R0e\n3bUW2knq6vCS5YMmD76/5UoU647BzB9CjgDzjuTKEbXL5AvcO5wWDgHSp7CA+2t4\nIFQvQMrPso5mvm2hNvD19vI0VjiY21rKgkJQAXSrLgkJg/fTL2wQiz10d2GnYsmx\nDeJCiBMwC+cmRW2eWePqaCPaWJwr92KsIiry+LgyGb3y01SUVV8kQgQXazutHqfu\ncQIDAQAB\n-----END PUBLIC KEY-----\n"
107

11-
pkey = OpenSSL::PKey.read(key)
8+
def test_pkey_read
9+
pkey = OpenSSL::PKey.read(KEY)
1210
assert_same OpenSSL::PKey::RSA, pkey.class
13-
assert pkey.public?
14-
assert_equal OpenSSL::PKey::RSA.new(key).n, pkey.n
15-
assert_equal OpenSSL::PKey::RSA.new(key).e, pkey.e
11+
assert_true pkey.public?
12+
assert_false pkey.private?
13+
assert_equal OpenSSL::PKey::RSA.new(KEY).n, pkey.n
14+
assert_equal OpenSSL::PKey::RSA.new(KEY).e, pkey.e
1615
end
1716

17+
def test_to_java
18+
pkey = OpenSSL::PKey.read(KEY)
19+
assert_kind_of java.security.PublicKey, pkey.to_java
20+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.PublicKey)
21+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.interfaces.RSAPublicKey)
22+
assert_kind_of java.security.PublicKey, pkey.to_java(java.security.Key)
23+
pub_key = pkey.to_java(java.security.PublicKey)
24+
if pub_key.is_a? org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey
25+
assert_kind_of java.security.PublicKey, pkey.to_java(org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey)
26+
end
27+
assert_raise_kind_of(TypeError) { pkey.to_java(java.security.interfaces.ECPublicKey) }
28+
# NOTE: won't fail as it's a marker that is neither a PublicKey or PrivateKey (also does not sub-class Key)
29+
#assert_raise_kind_of(TypeError) { pkey.to_java(java.security.interfaces.ECKey) }
30+
end if defined?(JRUBY_VERSION)
31+
1832
end

0 commit comments

Comments
 (0)