Skip to content

Commit

Permalink
[refactor] PKey.read to use BC fully when reading public keys
Browse files Browse the repository at this point in the history
  • Loading branch information
kares committed Apr 10, 2024
1 parent e60ec45 commit 6af9858
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/main/java/org/jruby/ext/openssl/PKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR
// d2i_PUBKEY_bio
try {
pubKey = org.jruby.ext.openssl.impl.PKey.readPublicKey(input);
} catch (IOException|GeneralSecurityException e) {
} catch (IOException e) {
debugStackTrace(runtime, "PKey readPublicKey", e); /* ignore */
}
// PEM_read_bio_PUBKEY
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/org/jruby/ext/openssl/impl/PKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
***** END LICENSE BLOCK *****/
package org.jruby.ext.openssl.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.math.BigInteger;

import java.security.KeyFactory;
Expand All @@ -51,6 +54,7 @@
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.spec.DHParameterSpec;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
Expand All @@ -69,6 +73,8 @@
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import org.jruby.ext.openssl.SecurityHelper;

Expand Down Expand Up @@ -132,17 +138,12 @@ public static KeyPair readPrivateKey(final Type type, final PrivateKeyInfo keyIn
}

// d2i_PUBKEY_bio
public static PublicKey readPublicKey(byte[] input) throws IOException, NoSuchAlgorithmException {
PublicKey key = null;
try {
key = readRSAPublicKey(input);
} catch (InvalidKeySpecException e) { /* ignore */ }
if (key == null) {
try {
key = readDSAPublicKey(input);
} catch (InvalidKeySpecException e) { /* ignore */ }
public static PublicKey readPublicKey(byte[] input) throws IOException {
try (Reader in = new InputStreamReader(new ByteArrayInputStream(input))) {
Object pemObject = new PEMParser(in).readObject();
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pemObject);
return new JcaPEMKeyConverter().getPublicKey(publicKeyInfo);
}
return key;
}

// d2i_RSAPrivateKey_bio
Expand Down
5 changes: 5 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec256-private-v2.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFZpgytOAXPVreqGsHPdD9pojw30bnlqfUAqFZ3V3/qeoAoGCCqGSM49
AwEHoUQDQgAE7JbAf3pWEEPje6NG+4dGOwIZnNwRFIe7DnQ4xFWKPrL5tVWlBh7N
DFhjGNhiyO+aQjbcx9uWV74ifq7i21Bemg==
-----END EC PRIVATE KEY-----
4 changes: 4 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec256-public-v2.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7JbAf3pWEEPje6NG+4dGOwIZnNwR
FIe7DnQ4xFWKPrL5tVWlBh7NDFhjGNhiyO+aQjbcx9uWV74ifq7i21Bemg==
-----END PUBLIC KEY-----
5 changes: 5 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec256k-private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIMTine3s8tT+8bswDM4/z8o+wIYGb9PQPrw8x6Nu6QDdoAcGBSuBBAAK
oUQDQgAEy8wuv6+fXodLPLfhxm132y1R8m4dkng7tHe7N+sULV2Eth6AxEXQfd+E
4nuceR21UNCvQKqxiYwCzVwIKcHe/A==
-----END EC PRIVATE KEY-----
4 changes: 4 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec256k-public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEy8wuv6+fXodLPLfhxm132y1R8m4dkng7
tHe7N+sULV2Eth6AxEXQfd+E4nuceR21UNCvQKqxiYwCzVwIKcHe/A==
-----END PUBLIC KEY-----
7 changes: 7 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec512-private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIB0/+ffxEj7j62xvGaB5pvzk888e412ESO/EK/K0QlS9dSF8+Rj1rG
zqpRB8fvDnoe8xdmkW/W5GKzojMyv7YQYumgBwYFK4EEACOhgYkDgYYABAEw74Yw
aTbPY6TtWmxx6LJDzCX2nKWCPnKdZcEH9Ncu8g5RjRBRq2yacja3OoS6nA2YeDng
reBJxZr376P6Ns6XcQFWDA6K/MCTrEBCsPxXZNxd8KR9vMGWhgNtWRrcKzwJfQkr
suyehZkbbYyFnAWyARKHZuV7VUXmeEmRS/f93MPqVA==
-----END EC PRIVATE KEY-----
6 changes: 6 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/ec512-public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBMO+GMGk2z2Ok7VpsceiyQ8wl9pyl
gj5ynWXBB/TXLvIOUY0QUatsmnI2tzqEupwNmHg54K3gScWa9++j+jbOl3EBVgwO
ivzAk6xAQrD8V2TcXfCkfbzBloYDbVka3Cs8CX0JK7LsnoWZG22MhZwFsgESh2bl
e1VF5nhJkUv3/dzD6lQ=
-----END PUBLIC KEY-----
27 changes: 27 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/rsa-2048-private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4GzZTLU48c4WbyvHi+QKrB71x+T0eq5hqDbQqnlYjhD1Ika7
io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lgCZr4+8UHbr1qf0Eu5HZSpszs2YxY
8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldHH/eazwnc3F/hgNsV0xjScVilejgo
cJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y0HFyrMsPoQyLuCUpr6ulOfrkr7ZO
dhAIG8r1HcjOp/AUjM15vfXcbUZjkM/VloifX1YitU3upMGJ8/DpFGffMOImrn5r
6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgVQQIDAQABAoIBAEH0Ozgr2fxWEInD
V/VooypKPvjr9F1JejGxSkmPN9MocKIOH3dsbZ1uEXa3ItBUxan4XlK06SNgp+tH
xULfF/Y6sQlsse59hBq50Uoa69dRShn1AP6JgZVvkduMPBNxUYL5zrs6emsQXb9Q
DglDRQfEAJ7vyxSIqQDxYcyT8uSUF70dqFe+E9B2VE3D6ccHc98k41pJrAFAUFH1
wwvDhfyYr7/Ultut9wzpZvU1meF3Vna3GOUHfxrG6wu1G+WIWHGjouzThsc1qiVI
BtMCJxuCt5fOXRbU4STbMqhB6sZHiOh6J/dZU6JwRYt+IS8FB6kCNFSEWZWQledJ
XqtYSQECgYEA9nmnFTRj3fTBq9zMXfCRujkSy6X2bOb39ftNXzHFuc+I6xmv/3Bs
P9tDdjueP/SnCb7i/9hXkpEIcxjrjiqgcvD2ym1hE4q+odMzRAXYMdnmzI34SVZE
U5hYJcYsXNKrTTleba7QgqdORmyJ9FwqLO40udvmrZMY223XDwgRkOkCgYEA6RkO
5wjjrWWp/G1YN3KXZTS1m2/eGrUThohXKAfAjbWWiouNLW2msXrxEWsPRL6xKiHu
X9cwZwzi3MstAgk+bphUGUVUkGKNDjWHJA25tDYjbPtkd6xbL4eCHsKpNL3HNYr9
N0CIvgn7qjaHRBem0iK7T6keY4axaSVddEwYapkCgYEA13K5qaB1F4Smcpt8DTWH
vPe8xUUaZlFzOJLmLCsuwmB2N8Ppg2j7RspcaxJsH021YaB5ftjWm+ipMSr8ZPY/
8JlPsNzxuYpTXtNmAbT2KYVm6THEch61dTk6/DIBf1YrpUJbl5by7vJeStL/uBmE
SGgksL5XIyzs0opuLdaIvFkCgYAyBLWE8AxjFfCvAQuwAj/ocLITo6KmWnrRIIqL
RXaVMgUWv7FQsTnW1cnK8g05tC2yG8vZ9wQk6Mf5lwOWb0NdWgSZ0528ydj41pWk
L+nMeN2LMjqxz2NVxJ8wWJcUgTCxFZ0WcRumo9/D+6V1ABpE9zz4cBLcSnfhVypB
nV6T6QKBgQCSZNCQ9HPxjAgYcsqc5sjNwuN1GHQZSav3Tye3k6zHENe1lsteT9K8
xciGIuhybKZBvB4yImIIHCtnH+AS+mHAGqHarjNDMfvjOq0dMibPx4+bkIiHdBIH
Xz+j5kmntvFiUnzr0Z/Tcqo+r8FvyCo1YWgwqGP8XoFrswD7gy7cZw==
-----END RSA PRIVATE KEY-----
9 changes: 9 additions & 0 deletions src/test/ruby/fixtures/pkey/custom/rsa-2048-public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4GzZTLU48c4WbyvHi+QK
rB71x+T0eq5hqDbQqnlYjhD1Ika7io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lg
CZr4+8UHbr1qf0Eu5HZSpszs2YxY8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldH
H/eazwnc3F/hgNsV0xjScVilejgocJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y
0HFyrMsPoQyLuCUpr6ulOfrkr7ZOdhAIG8r1HcjOp/AUjM15vfXcbUZjkM/Vloif
X1YitU3upMGJ8/DpFGffMOImrn5r6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgV
QQIDAQAB
-----END PUBLIC KEY-----
35 changes: 35 additions & 0 deletions src/test/ruby/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,41 @@ def test_pkey_read
assert_equal OpenSSL::PKey::RSA.new(KEY).e, pkey.e
end

def test_read_files
custom_fixtures_path = File.expand_path('fixtures/pkey/custom', File.dirname(__FILE__))

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256-private-v2.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.private_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256k-private.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.private_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256k-public.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.public_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec256-public-v2.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.public_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec512-private.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.private_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'ec512-public.pem')))
assert_equal OpenSSL::PKey::EC, key.class
assert key.public_key?

key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'rsa-2048-private.pem')))
assert_equal OpenSSL::PKey::RSA, key.class
assert key.private?
key = OpenSSL::PKey.read(File.read(File.join(custom_fixtures_path, 'rsa-2048-public.pem')))
assert_equal OpenSSL::PKey::RSA, key.class
assert key.public?
end

def test_pkey_read_pkcs8_and_check_with_cert
pkey = File.expand_path('pkey-pkcs8.pem', File.dirname(__FILE__))
pkey = OpenSSL::PKey.read(File.read(pkey), nil)
Expand Down

0 comments on commit 6af9858

Please sign in to comment.