diff --git a/src/main/java/net/schmizz/sshj/AndroidConfig.java b/src/main/java/net/schmizz/sshj/AndroidConfig.java index 9c230dd5..1dae34d6 100644 --- a/src/main/java/net/schmizz/sshj/AndroidConfig.java +++ b/src/main/java/net/schmizz/sshj/AndroidConfig.java @@ -23,6 +23,9 @@ import net.schmizz.sshj.signature.SignatureRSA; import net.schmizz.sshj.transport.random.JCERandom; import net.schmizz.sshj.transport.random.SingletonRandomFactory; +/** + * Registers SpongyCastle as JCE provider. + */ public class AndroidConfig extends DefaultConfig { @@ -30,13 +33,6 @@ public class AndroidConfig SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider"); } - public AndroidConfig(){ - super(); - initKeyExchangeFactories(true); - initRandomFactory(true); - initFileKeyProviderFactories(true); - } - // don't add ECDSA protected void initSignatureFactories() { setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory(), diff --git a/src/main/java/net/schmizz/sshj/DefaultConfig.java b/src/main/java/net/schmizz/sshj/DefaultConfig.java index b2400d6b..91cfe2f6 100644 --- a/src/main/java/net/schmizz/sshj/DefaultConfig.java +++ b/src/main/java/net/schmizz/sshj/DefaultConfig.java @@ -92,7 +92,7 @@ public class DefaultConfig properties.load(DefaultConfig.class.getClassLoader().getResourceAsStream("sshj.properties")); String property = properties.getProperty("sshj.version"); return "SSHJ_" + property.replace('-', '_'); // '-' is a disallowed character, see RFC-4253#section-4.2 - } catch (IOException e) { + } catch (Exception e) { log.error("Could not read the sshj.properties file, returning an 'unknown' version as fallback."); return "SSHJ_VERSION_UNKNOWN"; } diff --git a/src/main/java/net/schmizz/sshj/common/SecurityUtils.java b/src/main/java/net/schmizz/sshj/common/SecurityUtils.java index 96a0b884..eb4bab02 100644 --- a/src/main/java/net/schmizz/sshj/common/SecurityUtils.java +++ b/src/main/java/net/schmizz/sshj/common/SecurityUtils.java @@ -18,11 +18,21 @@ package net.schmizz.sshj.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.PublicKey; +import java.security.Security; +import java.security.Signature; + import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; -import java.security.*; import static java.lang.String.format; @@ -37,12 +47,17 @@ public class SecurityUtils { */ public static final String BOUNCY_CASTLE = "BC"; + /** + * Identifier for the BouncyCastle JCE provider + */ + public static final String SPONGY_CASTLE = "SC"; + /* * Security provider identifier. null = default JCE */ private static String securityProvider = null; - // relate to BC registration + // relate to BC registration (or SpongyCastle on Android) private static Boolean registerBouncyCastle; private static boolean registrationDone; @@ -82,6 +97,8 @@ public class SecurityUtils { return false; } + + public static synchronized Cipher getCipher(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { register(); @@ -222,11 +239,11 @@ public class SecurityUtils { * Attempts registering BouncyCastle as security provider if it has not been previously attempted and returns * whether the registration succeeded. * - * @return whether BC registered + * @return whether BC (or SC on Android) registered */ public static synchronized boolean isBouncyCastleRegistered() { register(); - return BOUNCY_CASTLE.equals(securityProvider); + return BOUNCY_CASTLE.equals(securityProvider) || SPONGY_CASTLE.equals(securityProvider); } public static synchronized void setRegisterBouncyCastle(boolean registerBouncyCastle) { diff --git a/src/main/java/net/schmizz/sshj/userauth/keyprovider/PKCS8KeyFile.java b/src/main/java/net/schmizz/sshj/userauth/keyprovider/PKCS8KeyFile.java index 2c012c3d..d7b42af3 100644 --- a/src/main/java/net/schmizz/sshj/userauth/keyprovider/PKCS8KeyFile.java +++ b/src/main/java/net/schmizz/sshj/userauth/keyprovider/PKCS8KeyFile.java @@ -16,6 +16,7 @@ package net.schmizz.sshj.userauth.keyprovider; import net.schmizz.sshj.common.IOUtils; +import net.schmizz.sshj.common.SecurityUtils; import net.schmizz.sshj.userauth.password.PasswordUtils; import org.bouncycastle.openssl.EncryptionException; import org.bouncycastle.openssl.PEMEncryptedKeyPair; @@ -62,12 +63,12 @@ public class PKCS8KeyFile extends BaseFileKeyProvider { final Object o = r.readObject(); final JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter(); - pemConverter.setProvider("BC"); + pemConverter.setProvider(SecurityUtils.getSecurityProvider()); if (o instanceof PEMEncryptedKeyPair) { final PEMEncryptedKeyPair encryptedKeyPair = (PEMEncryptedKeyPair) o; JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder(); - decryptorBuilder.setProvider("BC"); + decryptorBuilder.setProvider(SecurityUtils.getSecurityProvider()); try { passphrase = pwdf == null ? null : pwdf.reqPassword(resource); kp = pemConverter.getKeyPair(encryptedKeyPair.decryptKeyPair(decryptorBuilder.build(passphrase)));