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 1aacd117..686b1f27 100644 --- a/src/main/java/org/jruby/ext/openssl/impl/PKey.java +++ b/src/main/java/org/jruby/ext/openssl/impl/PKey.java @@ -43,11 +43,6 @@ import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPrivateKeySpec; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; @@ -72,23 +67,9 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x9.ECNamedCurveTable; -import org.bouncycastle.asn1.x9.X962Parameters; -import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.util.PrivateKeyFactory; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; -import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; -import org.bouncycastle.jce.spec.ECNamedCurveSpec; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; import org.jruby.ext.openssl.SecurityHelper; /** @@ -103,22 +84,12 @@ public enum Type { RSA, DSA, EC; } public static KeyPair readPrivateKey(final Type type, final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { - if (type == Type.EC) { - if (false) new PEMParser(null); - } - //OpenSSHPrivateKeyUtil parsePrivateKeyBlob return readPrivateKey(type, mockPrivateKeyInfo(type, input)); } private static PrivateKeyInfo mockPrivateKeyInfo(final Type type, final byte[] input) throws IOException { assert type != null; - AlgorithmIdentifier algId = null; - if (type == Type.EC) { - //algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey); // due readECPrivateKey - //algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(DERNull.INSTANCE)); // due readECPrivateKey - } - return new PrivateKeyInfo(algId, new ASN1InputStream(input).readObject()); - //return PrivateKeyInfo.getInstance(input); NOPE! + return new PrivateKeyInfo(null, new ASN1InputStream(input).readObject()); } public static KeyPair readPrivateKey(final Type type, final PrivateKeyInfo keyInfo) @@ -298,107 +269,26 @@ public static KeyPair readECPrivateKey(final byte[] input) public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final byte[] input) throws IOException, InvalidKeySpecException { return readECPrivateKey(keyFactory, mockPrivateKeyInfo(Type.EC, input)); - - //PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(input); - //return new KeyPair(null, keyFactory.generatePrivate(spec)); } -// private static PublicKey resolveECPublicKey(final KeyFactory keyFactory, ECPrivateKey privateKey) -// throws InvalidKeySpecException { -// -// final ECParameterSpec params = privateKey.getParams(); -// ECPoint q = params.getGenerator().multiply(privateKey.getS()); // getD -// -// ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(q, ecParams); -// -// return keyFactory.generatePublic(publicKeySpec); -// } - public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final PrivateKeyInfo keyInfo) throws IOException, InvalidKeySpecException { try { ASN1Sequence seq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); - org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); + org.bouncycastle.asn1.sec.ECPrivateKey key = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); - PrivateKeyInfo privInfo; - if (algId == null) { - algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); - privInfo = new PrivateKeyInfo(algId, pKey); - } else { - + if (algId == null) { // mockPrivateKeyInfo + algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, key.getParameters()); } - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); - privInfo = new PrivateKeyInfo(algId, pKey); - - if (true) { - 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(new X509EncodedKeySpec(pubInfo.getEncoded())), privateKey); - } - - - //ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters) PrivateKeyFactory.createKey(keyInfo); - //AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); -// X962Parameters params = X962Parameters.getInstance(algId.getParameters()); -// -// X9ECParameters x9; -// if (params.isNamedCurve()) -// { -// ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); -// x9 = ECNamedCurveTable.getByOID(oid); -// } -// else -// { -// x9 = X9ECParameters.getInstance(params.getParameters()); -// } - - org.bouncycastle.asn1.sec.ECPrivateKey ecPrivateKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); - -// ASN1ObjectIdentifier curveOID = ASN1ObjectIdentifier.getInstance(ecPrivateKey.getParametersObject()); -// ECUtil.getNamedCurveByOid(curveOID); -// X9ECParameters x9Params = ECNamedCurveTable.getByOID(curveOID); -// -// ECDomainParameters dParams = new ECDomainParameters(x9Params.getCurve(), x9Params.getG(), x9Params.getN(), x9Params.getH(), x9Params.getSeed()); -// ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters(ecPrivateKey.getKey(), dParams); - -// org.bouncycastle.asn1.sec.ECPrivateKey ecPrivateKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); -// AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); - - /// -// if (key.getParameters() == null) { -// -// } -// ASN1ObjectIdentifier curveOID = ASN1ObjectIdentifier.getInstance(key.getParameters()); -// X9ECParameters ecParams = ECNamedCurveTable.getByOID(curveOID); -// ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters(key.getKey(), new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN(), ecParams.getH())); - - - // NOTE: should only happen when using mockPrivateKeyInfo(Type, byte[]) - //if (algId == null) algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey); - - //SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, ecPrivateKey.getPublicKey().getBytes()); - //ECPublicKeyParameters params = (ECPublicKeyParameters) PublicKeyFactory.createKey(pubInfo); -// key.getKey(); // publcKey BigInteger - - System.out.println("publicInfo: " + pubInfo); - System.out.println("key: " + ecPrivateKey.getKey()); - System.out.println("params: " + ecPrivateKey.getParameters()); - - //PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyInfo.getEncoded()); - PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded()); - //EncodedKeySpec privSpec = new OpenSSHPrivateKeySpec(ecPrivateKey.getEncoded()); - X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); - -// ECPrivateKeySpec privSpec = new ECPrivateKeySpec(privKeyParams.getD(), EC5Util.convertToSpec(privKeyParams.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