mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
Android Compability, again ;-) (#392)
* Rework SecurityUtils and PKCS8KeyFile for usage with SpongyCastle. * Specifying providerName for registration is unneccessary. * Update AndroidConfig, fix imports. * Workaround for Android 5.0 bug when SpongyCastle is the default JCE provider. On Android 5.0 reading the version from the jar does throw a SecurityException due to a bug in Android (see https://issuetracker.google.com/issues/36993752). Including that Exception in the catch provides a workaround for that issue.
This commit is contained in:
committed by
Jeroen van Erp
parent
d55eb6d02e
commit
39b72eed62
@@ -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(),
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)));
|
||||
|
||||
Reference in New Issue
Block a user