diff --git a/src/main/java/org/jruby/ext/openssl/impl/PKey.java b/src/main/java/org/jruby/ext/openssl/impl/PKey.java index ad623610..686b1f27 100644 --- a/src/main/java/org/jruby/ext/openssl/impl/PKey.java +++ b/src/main/java/org/jruby/ext/openssl/impl/PKey.java @@ -88,6 +88,7 @@ public static KeyPair readPrivateKey(final Type type, final byte[] input) } private static PrivateKeyInfo mockPrivateKeyInfo(final Type type, final byte[] input) throws IOException { + assert type != null; return new PrivateKeyInfo(null, new ASN1InputStream(input).readObject()); } @@ -273,20 +274,21 @@ public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final byte[] public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final PrivateKeyInfo keyInfo) throws IOException, InvalidKeySpecException { try { - org.bouncycastle.asn1.sec.ECPrivateKey key = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); - AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); - // NOTE: should only happen when using mockPrivateKeyInfo(Type, byte[]) - if (algId == null) algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey); + ASN1Sequence seq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, key.getPublicKey().getBytes()); - PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyInfo.getEncoded()); - X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); + org.bouncycastle.asn1.sec.ECPrivateKey key = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); + AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); + if (algId == null) { // mockPrivateKeyInfo + algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, key.getParameters()); + } + final SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, key.getPublicKey().getBytes()); + final PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, key); - ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(privSpec); + ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privInfo.getEncoded())); if (algId.getParameters() instanceof ASN1ObjectIdentifier) { privateKey = ECPrivateKeyWithName.wrap(privateKey, (ASN1ObjectIdentifier) algId.getParameters()); } - return new KeyPair(keyFactory.generatePublic(pubSpec), privateKey); + return new KeyPair(keyFactory.generatePublic(new X509EncodedKeySpec(pubInfo.getEncoded())), privateKey); } catch (ClassCastException ex) { throw new IOException("wrong ASN.1 object found in stream", ex); diff --git a/src/test/ruby/ec/test_ec.rb b/src/test/ruby/ec/test_ec.rb index 0cd685e2..bcc2312e 100644 --- a/src/test/ruby/ec/test_ec.rb +++ b/src/test/ruby/ec/test_ec.rb @@ -55,8 +55,12 @@ def test_read_pkcs8_with_ec key_file = File.join(File.dirname(__FILE__), 'private_key_pkcs8.pem') key = OpenSSL::PKey::read(File.read(key_file)) + assert_equal OpenSSL::PKey::EC, key.class assert_equal '37273549501637553234010607973347901861080883009977847480473501706546896416762', key.private_key.to_s - assert_empty key.public_key.to_s + + assert_equal OpenSSL::PKey::EC::Point, key.public_key.class + public_key = '59992919564038617581477192805085606797983518604284049179473294859597640027055772972320536875319417493705914919226919250526441868144324498122209513139102397' + assert_equal public_key, key.public_key.to_bn.to_s end def test_point