Skip to content

Commit 39b72ee

Browse files
eidottermihihierynomus
authored andcommitted
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.
1 parent d55eb6d commit 39b72ee

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

src/main/java/net/schmizz/sshj/AndroidConfig.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,16 @@
2323
import net.schmizz.sshj.transport.random.JCERandom;
2424
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
2525

26+
/**
27+
* Registers SpongyCastle as JCE provider.
28+
*/
2629
public class AndroidConfig
2730
extends DefaultConfig {
2831

2932
static {
3033
SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider");
3134
}
3235

33-
public AndroidConfig(){
34-
super();
35-
initKeyExchangeFactories(true);
36-
initRandomFactory(true);
37-
initFileKeyProviderFactories(true);
38-
}
39-
4036
// don't add ECDSA
4137
protected void initSignatureFactories() {
4238
setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory(),

src/main/java/net/schmizz/sshj/DefaultConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ private String readVersionFromProperties() {
9292
properties.load(DefaultConfig.class.getClassLoader().getResourceAsStream("sshj.properties"));
9393
String property = properties.getProperty("sshj.version");
9494
return "SSHJ_" + property.replace('-', '_'); // '-' is a disallowed character, see RFC-4253#section-4.2
95-
} catch (IOException e) {
95+
} catch (Exception e) {
9696
log.error("Could not read the sshj.properties file, returning an 'unknown' version as fallback.");
9797
return "SSHJ_VERSION_UNKNOWN";
9898
}

src/main/java/net/schmizz/sshj/common/SecurityUtils.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,21 @@
1818
import org.slf4j.Logger;
1919
import org.slf4j.LoggerFactory;
2020

21+
import java.security.GeneralSecurityException;
22+
import java.security.KeyFactory;
23+
import java.security.KeyPairGenerator;
24+
import java.security.MessageDigest;
25+
import java.security.NoSuchAlgorithmException;
26+
import java.security.NoSuchProviderException;
27+
import java.security.Provider;
28+
import java.security.PublicKey;
29+
import java.security.Security;
30+
import java.security.Signature;
31+
2132
import javax.crypto.Cipher;
2233
import javax.crypto.KeyAgreement;
2334
import javax.crypto.Mac;
2435
import javax.crypto.NoSuchPaddingException;
25-
import java.security.*;
2636

2737
import static java.lang.String.format;
2838

@@ -37,12 +47,17 @@ public class SecurityUtils {
3747
*/
3848
public static final String BOUNCY_CASTLE = "BC";
3949

50+
/**
51+
* Identifier for the BouncyCastle JCE provider
52+
*/
53+
public static final String SPONGY_CASTLE = "SC";
54+
4055
/*
4156
* Security provider identifier. null = default JCE
4257
*/
4358
private static String securityProvider = null;
4459

45-
// relate to BC registration
60+
// relate to BC registration (or SpongyCastle on Android)
4661
private static Boolean registerBouncyCastle;
4762
private static boolean registrationDone;
4863

@@ -82,6 +97,8 @@ public static boolean registerSecurityProvider(String providerClassName) {
8297
return false;
8398
}
8499

100+
101+
85102
public static synchronized Cipher getCipher(String transformation)
86103
throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException {
87104
register();
@@ -222,11 +239,11 @@ public static synchronized Signature getSignature(String algorithm)
222239
* Attempts registering BouncyCastle as security provider if it has not been previously attempted and returns
223240
* whether the registration succeeded.
224241
*
225-
* @return whether BC registered
242+
* @return whether BC (or SC on Android) registered
226243
*/
227244
public static synchronized boolean isBouncyCastleRegistered() {
228245
register();
229-
return BOUNCY_CASTLE.equals(securityProvider);
246+
return BOUNCY_CASTLE.equals(securityProvider) || SPONGY_CASTLE.equals(securityProvider);
230247
}
231248

232249
public static synchronized void setRegisterBouncyCastle(boolean registerBouncyCastle) {

src/main/java/net/schmizz/sshj/userauth/keyprovider/PKCS8KeyFile.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package net.schmizz.sshj.userauth.keyprovider;
1717

1818
import net.schmizz.sshj.common.IOUtils;
19+
import net.schmizz.sshj.common.SecurityUtils;
1920
import net.schmizz.sshj.userauth.password.PasswordUtils;
2021
import org.bouncycastle.openssl.EncryptionException;
2122
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
@@ -62,12 +63,12 @@ protected KeyPair readKeyPair()
6263
final Object o = r.readObject();
6364

6465
final JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
65-
pemConverter.setProvider("BC");
66+
pemConverter.setProvider(SecurityUtils.getSecurityProvider());
6667

6768
if (o instanceof PEMEncryptedKeyPair) {
6869
final PEMEncryptedKeyPair encryptedKeyPair = (PEMEncryptedKeyPair) o;
6970
JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
70-
decryptorBuilder.setProvider("BC");
71+
decryptorBuilder.setProvider(SecurityUtils.getSecurityProvider());
7172
try {
7273
passphrase = pwdf == null ? null : pwdf.reqPassword(resource);
7374
kp = pemConverter.getKeyPair(encryptedKeyPair.decryptKeyPair(decryptorBuilder.build(passphrase)));

0 commit comments

Comments
 (0)