From 0a1855a611bc09c627b6d8120506b1b5cd948b16 Mon Sep 17 00:00:00 2001 From: kares Date: Thu, 4 Apr 2024 08:00:49 +0200 Subject: [PATCH] [refactor] PKey read-er methods and return types --- src/main/java/org/jruby/ext/openssl/PKey.java | 35 +++++++++------ .../java/org/jruby/ext/openssl/impl/PKey.java | 45 +++++++------------ .../ext/openssl/x509store/PEMInputOutput.java | 20 ++++----- 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/jruby/ext/openssl/PKey.java b/src/main/java/org/jruby/ext/openssl/PKey.java index af0442cf..5191dac4 100644 --- a/src/main/java/org/jruby/ext/openssl/PKey.java +++ b/src/main/java/org/jruby/ext/openssl/PKey.java @@ -27,10 +27,8 @@ ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; -import java.io.ByteArrayInputStream; import java.io.Console; import java.io.IOException; -import java.io.InputStreamReader; import java.io.StringReader; import java.math.BigInteger; import java.security.*; @@ -57,11 +55,12 @@ import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; +import org.jruby.util.ByteList; +import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.x509store.PEMInputOutput; + import static org.jruby.ext.openssl.OpenSSL.*; -import org.jruby.ext.openssl.impl.CipherSpec; -import org.jruby.util.ByteList; /** * @author Ola Bini @@ -111,14 +110,16 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR } final RubyString str = readInitArg(context, data); - Object key = null; + KeyPair keyPair; // d2i_PrivateKey_bio try { - key = readPrivateKey(str, pass); - } catch (IOException e) { /* ignore */ } + keyPair = readPrivateKey(str, pass); + } catch (IOException e) { + debugStackTrace(runtime, "PKey readPrivateKey", e); /* ignore */ + keyPair = null; + } // PEM_read_bio_PrivateKey - if (key != null) { - final KeyPair keyPair = (KeyPair) key; + if (keyPair != null) { final String alg = getAlgorithm(keyPair); if ( "RSA".equals(alg) ) { return new PKeyRSA(runtime, _PKey(runtime).getClass("RSA"), @@ -141,17 +142,23 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR try { pubKey = PEMInputOutput.readRSAPublicKey(new StringReader(str.toString()), null); return new PKeyRSA(runtime, (RSAPublicKey) pubKey); - } catch (IOException e) { /* ignore */ } + } catch (IOException e) { + debugStackTrace(runtime, "PKey readRSAPublicKey", e); /* ignore */ + } try { pubKey = PEMInputOutput.readDSAPublicKey(new StringReader(str.toString()), null); return new PKeyDSA(runtime, (DSAPublicKey) pubKey); - } catch (IOException e) { /* ignore */ } + } catch (IOException e) { + debugStackTrace(runtime, "PKey readDSAPublicKey", e); /* ignore */ + } final byte[] input = StringHelper.readX509PEM(context, str); // d2i_PUBKEY_bio try { pubKey = org.jruby.ext.openssl.impl.PKey.readPublicKey(input); - } catch (IOException|GeneralSecurityException e) { /* ignore */ } + } catch (IOException|GeneralSecurityException e) { + debugStackTrace(runtime, "PKey readPublicKey", e); /* ignore */ + } // PEM_read_bio_PUBKEY if (pubKey == null) { try { @@ -431,12 +438,12 @@ protected static boolean ttySTDIN(final ThreadContext context) { catch (RaiseException ex) { return false; } } - static Object readPrivateKey(final String str, final char[] passwd) + static KeyPair readPrivateKey(final String str, final char[] passwd) throws PEMInputOutput.PasswordRequiredException, IOException { return PEMInputOutput.readPrivateKey(new StringReader(str), passwd); } - static Object readPrivateKey(final RubyString str, final char[] passwd) + static KeyPair readPrivateKey(final RubyString str, final char[] passwd) throws PEMInputOutput.PasswordRequiredException, IOException { return readPrivateKey(str.toString(), passwd); } 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 d54d5817..23a4cf2e 100644 --- a/src/main/java/org/jruby/ext/openssl/impl/PKey.java +++ b/src/main/java/org/jruby/ext/openssl/impl/PKey.java @@ -88,9 +88,13 @@ public class PKey { public static KeyPair readPrivateKey(final byte[] input, final String type) + throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + return readPrivateKey((ASN1Sequence) new ASN1InputStream(input).readObject(), type); + } + + public static KeyPair readPrivateKey(final ASN1Sequence seq, final String type) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { KeySpec pubSpec; KeySpec privSpec; - ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( type.equals("RSA") ) { ASN1Integer mod = (ASN1Integer) seq.getObjectAt(1); ASN1Integer pubExp = (ASN1Integer) seq.getObjectAt(2); @@ -114,7 +118,7 @@ else if ( type.equals("DSA") ) { pubSpec = new DSAPublicKeySpec(y.getValue(), p.getValue(), q.getValue(), g.getValue()); } else if ( type.equals("EC") ) { - return readECPrivateKey(input); + return readECPrivateKey(SecurityHelper.getKeyFactory("EC"), seq); } else { throw new IllegalStateException("unsupported type: " + type); @@ -123,29 +127,6 @@ else if ( type.equals("EC") ) { return new KeyPair(fact.generatePublic(pubSpec), fact.generatePrivate(privSpec)); } - // d2i_PrivateKey_bio - public static KeyPair readPrivateKey(byte[] input) throws IOException, - NoSuchAlgorithmException, InvalidKeySpecException { - KeyPair key = null; - try { - key = readRSAPrivateKey(input); - } - catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } - catch (InvalidKeySpecException e) { - // ignore - } - if (key == null) { - try { - key = readDSAPrivateKey(input); - } - catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } - catch (InvalidKeySpecException e) { - // ignore - } - } - return key; - } - // d2i_PUBKEY_bio public static PublicKey readPublicKey(byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { @@ -281,22 +262,26 @@ public static KeyPair readECPrivateKey(final byte[] input) return readECPrivateKey(SecurityHelper.getKeyFactory("EC"), input); } - public static KeyPair readECPrivateKey(final KeyFactory ecFactory, final byte[] input) + public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final byte[] input) + throws IOException, InvalidKeySpecException { + return readECPrivateKey(keyFactory, (ASN1Sequence) ASN1Primitive.fromByteArray(input)); + } + + public static KeyPair readECPrivateKey(final KeyFactory keyFactory, final ASN1Sequence input) throws IOException, InvalidKeySpecException { try { - org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(ASN1Primitive.fromByteArray(input)); + org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(input); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParametersObject().toASN1Primitive()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.toASN1Primitive()); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privInfo.getEncoded()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); - //KeyFactory fact = KeyFactory.getInstance("EC", provider); - ECPrivateKey privateKey = (ECPrivateKey) ecFactory.generatePrivate(privSpec); + ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(privSpec); if ( algId.getParameters() instanceof ASN1ObjectIdentifier ) { privateKey = ECPrivateKeyWithName.wrap(privateKey, (ASN1ObjectIdentifier) algId.getParameters()); } - return new KeyPair(ecFactory.generatePublic(pubSpec), privateKey); + return new KeyPair(keyFactory.generatePublic(pubSpec), privateKey); } catch (ClassCastException ex) { throw new IOException("wrong ASN.1 object found in stream", ex); diff --git a/src/main/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java b/src/main/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java index 3e554f12..99759f7a 100644 --- a/src/main/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java +++ b/src/main/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java @@ -1486,23 +1486,23 @@ private static CMSSignedData readPKCS7(BufferedReader in, char[] p, String endMa public static KeyFactory getKeyFactory(final AlgorithmIdentifier algId) throws NoSuchAlgorithmException { + return SecurityHelper.getKeyFactory(getPrivateKeyType(algId)); + } + private static String getPrivateKeyType(final AlgorithmIdentifier algId) { final ASN1ObjectIdentifier algIdentifier = algId.getAlgorithm(); - String algorithm = null; - if ( X9ObjectIdentifiers.id_ecPublicKey.equals(algIdentifier) ) { - algorithm = "EC"; + if (X9ObjectIdentifiers.id_ecPublicKey.equals(algIdentifier)) { + return "EC"; } - else if ( PKCSObjectIdentifiers.rsaEncryption.equals(algIdentifier) ) { - algorithm = "RSA"; + if (PKCSObjectIdentifiers.rsaEncryption.equals(algIdentifier)) { + return "RSA"; } - else if ( X9ObjectIdentifiers.id_dsa.equals(algIdentifier) ) { - algorithm = "DSA"; + if (X9ObjectIdentifiers.id_dsa.equals(algIdentifier)) { + return "DSA"; } - if ( algorithm == null ) algorithm = algIdentifier.getId(); - - return SecurityHelper.getKeyFactory(algorithm); + return algIdentifier.getId(); } private static CertificateFactory getX509CertificateFactory() {