diff --git a/src/main/java/net/schmizz/sshj/AndroidConfig.java b/src/main/java/net/schmizz/sshj/AndroidConfig.java index 802f511f..235d9fab 100644 --- a/src/main/java/net/schmizz/sshj/AndroidConfig.java +++ b/src/main/java/net/schmizz/sshj/AndroidConfig.java @@ -1,5 +1,5 @@ -/** - * Copyright 2009 sshj contributors +/* + * Copyright (C)2009 - SSHJ Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,6 @@ */ package net.schmizz.sshj; -import java.security.Provider; -import java.security.Security; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import net.schmizz.sshj.common.SecurityUtils; import net.schmizz.sshj.signature.SignatureDSA; import net.schmizz.sshj.signature.SignatureRSA; @@ -31,26 +25,14 @@ public class AndroidConfig extends DefaultConfig { static { - final Logger log = LoggerFactory.getLogger(AndroidConfig.class); - SecurityUtils.setRegisterBouncyCastle(false); - try { - Class bcpClazz = Class.forName("org.spongycastle.jce.provider.BouncyCastleProvider"); - Security.addProvider((Provider) bcpClazz.newInstance()); - SecurityUtils.setSecurityProvider("SC"); - } catch (ClassNotFoundException e) { - log.info("SpongyCastle was not found."); - } catch (IllegalAccessException e) { - log.error("IllegalAccessException", e); - } catch (InstantiationException e) { - log.info("InstantiationException", e); - } + SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider"); } // don't add ECDSA protected void initSignatureFactories() { setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory()); } - + @Override protected void initRandomFactory(boolean ignored) { setRandomFactory(new SingletonRandomFactory(new JCERandom.Factory())); diff --git a/src/main/java/net/schmizz/sshj/DefaultConfig.java b/src/main/java/net/schmizz/sshj/DefaultConfig.java index 06372a2c..98625521 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 } protected void initKeyExchangeFactories(boolean bouncyCastleRegistered) { - if (bouncyCastleRegistered) + if (bouncyCastleRegistered) { setKeyExchangeFactories(new Curve25519SHA256.Factory(), new DHGexSHA256.Factory(), new ECDHNistP.Factory521(), @@ -101,8 +101,9 @@ public class DefaultConfig new DHGexSHA1.Factory(), new DHG14.Factory(), new DHG1.Factory()); - else + } else { setKeyExchangeFactories(new DHG1.Factory(), new DHGexSHA1.Factory()); + } } protected void initRandomFactory(boolean bouncyCastleRegistered) { diff --git a/src/main/java/net/schmizz/sshj/common/SecurityUtils.java b/src/main/java/net/schmizz/sshj/common/SecurityUtils.java index 4453d37e..67ff7669 100644 --- a/src/main/java/net/schmizz/sshj/common/SecurityUtils.java +++ b/src/main/java/net/schmizz/sshj/common/SecurityUtils.java @@ -15,40 +15,25 @@ */ package net.schmizz.sshj.common; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import java.security.*; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; -import java.security.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -// TODO refactor +import static java.lang.String.format; -/** Static utility method relating to security facilities. */ +/** + * Static utility method relating to security facilities. + */ public class SecurityUtils { - - private static class BouncyCastleRegistration { - - public void run() - throws Exception { - if (java.security.Security.getProvider(BOUNCY_CASTLE) == null) { - LOG.debug("Trying to register BouncyCastle as a JCE provider"); - java.security.Security.addProvider(new BouncyCastleProvider()); - MessageDigest.getInstance("MD5", BOUNCY_CASTLE); - KeyAgreement.getInstance("DH", BOUNCY_CASTLE); - LOG.info("BouncyCastle registration succeeded"); - } else - LOG.info("BouncyCastle already registered as a JCE provider"); - securityProvider = BOUNCY_CASTLE; - } - } - private static final Logger LOG = LoggerFactory.getLogger(SecurityUtils.class); - /** Identifier for the BouncyCastle JCE provider */ + /** + * Identifier for the BouncyCastle JCE provider + */ public static final String BOUNCY_CASTLE = "BC"; /* @@ -60,6 +45,42 @@ public class SecurityUtils { private static Boolean registerBouncyCastle; private static boolean registrationDone; + public static boolean registerSecurityProvider(String providerClassName) { + Provider provider = null; + try { + Class name = Class.forName(providerClassName); + provider = (Provider) name.newInstance(); + } catch (ClassNotFoundException e) { + LOG.info("Security Provider class '{}' not found", providerClassName); + } catch (InstantiationException e) { + LOG.info("Security Provider class '{}' could not be created", providerClassName); + } catch (IllegalAccessException e) { + LOG.info("Security Provider class '{}' could not be accessed", providerClassName); + } + + if (provider == null) { + return false; + } + + try { + if (Security.getProvider(provider.getName()) == null) { + Security.addProvider(provider); + } + + if (securityProvider == null) { + MessageDigest.getInstance("MD5", provider.getName()); + KeyAgreement.getInstance("DH", provider.getName()); + setSecurityProvider(provider.getName()); + return true; + } + } catch (NoSuchAlgorithmException e) { + LOG.info(format("Security Provider '%s' does not support necessary algorithm", providerClassName), e); + } catch (NoSuchProviderException e) { + LOG.info("Registration of Security Provider '{}' unexpectedly failed", providerClassName); + } + return false; + } + public static synchronized Cipher getCipher(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { register(); @@ -73,9 +94,7 @@ public class SecurityUtils { * Computes the fingerprint for a public key, in the standard SSH format, e.g. "4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21" * * @param key the public key - * * @return the fingerprint - * * @see specification */ public static String getFingerprint(PublicKey key) { @@ -98,9 +117,7 @@ public class SecurityUtils { * Creates a new instance of {@link KeyAgreement} with the given algorithm. * * @param algorithm key agreement algorithm - * * @return new instance - * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ @@ -117,9 +134,7 @@ public class SecurityUtils { * Creates a new instance of {@link KeyFactory} with the given algorithm. * * @param algorithm key factory algorithm e.g. RSA, DSA - * * @return new instance - * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ @@ -136,9 +151,7 @@ public class SecurityUtils { * Creates a new instance of {@link KeyPairGenerator} with the given algorithm. * * @param algorithm key pair generator algorithm - * * @return new instance - * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ @@ -155,9 +168,7 @@ public class SecurityUtils { * Create a new instance of {@link Mac} with the given algorithm. * * @param algorithm MAC algorithm - * * @return new instance - * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ @@ -174,9 +185,7 @@ public class SecurityUtils { * Create a new instance of {@link MessageDigest} with the given algorithm. * * @param algorithm MessageDigest algorithm name - * * @return new instance - * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException */ @@ -236,20 +245,16 @@ public class SecurityUtils { private static void register() { if (!registrationDone) { - if (securityProvider == null && (registerBouncyCastle == null || registerBouncyCastle)) - // Use an inner class to avoid a strong dependency on BouncyCastle - try { - new BouncyCastleRegistration().run(); - } catch (Throwable t) { - if (registerBouncyCastle == null) - LOG.info("BouncyCastle not registered, using the default JCE provider"); - else { - LOG.error("Failed to register BouncyCastle as the defaut JCE provider"); - throw new SSHRuntimeException("Failed to register BouncyCastle as the defaut JCE provider", t); - } + if (securityProvider == null && (registerBouncyCastle == null || registerBouncyCastle)) { + registerSecurityProvider("org.bouncycastle.jce.provider.BouncyCastleProvider"); + if (securityProvider == null && registerBouncyCastle == null) { + LOG.info("BouncyCastle not registered, using the default JCE provider"); + } else if (securityProvider == null) { + LOG.error("Failed to register BouncyCastle as the defaut JCE provider"); + throw new SSHRuntimeException("Failed to register BouncyCastle as the defaut JCE provider"); } - registrationDone = true; + } } + registrationDone = true; } - }