Skip to content

Commit 401749e

Browse files
committed
[fix] restore PKCS#8 EC key handling (see #292)
1 parent e24d02f commit 401749e

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public static KeyPair readPrivateKey(final Type type, final byte[] input)
8888
}
8989

9090
private static PrivateKeyInfo mockPrivateKeyInfo(final Type type, final byte[] input) throws IOException {
91+
assert type != null;
9192
return new PrivateKeyInfo(null, new ASN1InputStream(input).readObject());
9293
}
9394

@@ -273,20 +274,21 @@ public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final byte[]
273274
public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final PrivateKeyInfo keyInfo)
274275
throws IOException, InvalidKeySpecException {
275276
try {
276-
org.bouncycastle.asn1.sec.ECPrivateKey key = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
277-
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
278-
// NOTE: should only happen when using mockPrivateKeyInfo(Type, byte[])
279-
if (algId == null) algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey);
277+
ASN1Sequence seq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey());
280278

281-
SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, key.getPublicKey().getBytes());
282-
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyInfo.getEncoded());
283-
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded());
279+
org.bouncycastle.asn1.sec.ECPrivateKey key = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq);
280+
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
281+
if (algId == null) { // mockPrivateKeyInfo
282+
algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, key.getParameters());
283+
}
284+
final SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, key.getPublicKey().getBytes());
285+
final PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, key);
284286

285-
ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(privSpec);
287+
ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privInfo.getEncoded()));
286288
if (algId.getParameters() instanceof ASN1ObjectIdentifier) {
287289
privateKey = ECPrivateKeyWithName.wrap(privateKey, (ASN1ObjectIdentifier) algId.getParameters());
288290
}
289-
return new KeyPair(keyFactory.generatePublic(pubSpec), privateKey);
291+
return new KeyPair(keyFactory.generatePublic(new X509EncodedKeySpec(pubInfo.getEncoded())), privateKey);
290292
}
291293
catch (ClassCastException ex) {
292294
throw new IOException("wrong ASN.1 object found in stream", ex);

src/test/ruby/ec/test_ec.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ def test_read_pkcs8_with_ec
5555
key_file = File.join(File.dirname(__FILE__), 'private_key_pkcs8.pem')
5656

5757
key = OpenSSL::PKey::read(File.read(key_file))
58+
assert_equal OpenSSL::PKey::EC, key.class
5859
assert_equal '37273549501637553234010607973347901861080883009977847480473501706546896416762', key.private_key.to_s
59-
assert_empty key.public_key.to_s
60+
61+
assert_equal OpenSSL::PKey::EC::Point, key.public_key.class
62+
public_key = '59992919564038617581477192805085606797983518604284049179473294859597640027055772972320536875319417493705914919226919250526441868144324498122209513139102397'
63+
assert_equal public_key, key.public_key.to_bn.to_s
6064
end
6165

6266
def test_point

0 commit comments

Comments
 (0)