Skip to content

Commit b07bf83

Browse files
committed
[fix] read back DER written by PKey#to_der
PKey.read only tried PKCS#8 on DER input
1 parent 2742145 commit b07bf83

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ private static IRubyObject readImpl(final ThreadContext context, IRubyObject...
172172
LOG.debugStack(runtime, "readPrivateKeyFromDER", e); /* ignore */
173173
}
174174
}
175+
// d2i_PrivateKey_bio - PKCS#1 RSA, DSA and SEC1 EC keys (as written by #to_der)
176+
if (keyPair == null) {
177+
try {
178+
keyPair = org.jruby.ext.openssl.impl.PKey.readPrivateKeyDER(str.getBytes());
179+
} catch (IOException e) {
180+
LOG.debugStack(runtime, "readPrivateKeyDER", e); /* ignore */
181+
}
182+
}
175183
// PEM_read_bio_PrivateKey
176184
if (keyPair != null) {
177185
final String alg = getAlgorithm(keyPair);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,20 @@ public static KeyPair readRSAPrivateKey(final KeyFactory rsaFactory, final byte[
236236
return null;
237237
}
238238

239+
// d2i_PrivateKey_bio - type specific DER encodings (PKCS#1 RSA, DSA, SEC1 EC)
240+
public static KeyPair readPrivateKeyDER(final byte[] input) throws IOException {
241+
try {
242+
// each reader matches on sequence shape so order does not matter
243+
KeyPair keyPair = readRSAPrivateKey(input);
244+
if (keyPair == null) keyPair = readDSAPrivateKey(input);
245+
if (keyPair == null) keyPair = readECPrivateKey(input);
246+
return keyPair;
247+
}
248+
catch (Exception e) { // the EC reader mocks up a PrivateKeyInfo and blows up in all sorts of ways
249+
throw new IOException("Could not parse private key: " + e.getMessage(), e);
250+
}
251+
}
252+
239253
// d2i_RSAPublicKey_bio
240254
public static PublicKey readRSAPublicKey(final byte[] input)
241255
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

test/test_pkey.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ def test_pkey_read_pkcs8_and_check_with_cert
6767
assert_true cert.check_private_key(pkey)
6868
end
6969

70+
# #to_der writes PKCS#1 (RSA, DSA) or SEC1 (EC), PKey.read only handled PKCS#8
71+
def test_pkey_read_der_round_trip
72+
%w[rsa2048 dsa2048 p256].each do |name|
73+
key = Fixtures.pkey(name)
74+
read = OpenSSL::PKey.read(key.to_der)
75+
assert_instance_of key.class, read
76+
assert_equal key.to_der, read.to_der
77+
end
78+
end
79+
7080
# MRI also reports provider=... which has no meaning in terms of Java
7181
def test_pkey_inspect
7282
rsa = OpenSSL::PKey::RSA.new(2048)

0 commit comments

Comments
 (0)