Refactored SecurityUtils a bit

This commit is contained in:
Jeroen van Erp
2016-09-30 10:37:55 +02:00
parent 655d070571
commit 275e98e55b
3 changed files with 62 additions and 74 deletions

View File

@@ -1,5 +1,5 @@
/** /*
* Copyright 2009 sshj contributors * Copyright (C)2009 - SSHJ Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,12 +15,6 @@
*/ */
package net.schmizz.sshj; 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.common.SecurityUtils;
import net.schmizz.sshj.signature.SignatureDSA; import net.schmizz.sshj.signature.SignatureDSA;
import net.schmizz.sshj.signature.SignatureRSA; import net.schmizz.sshj.signature.SignatureRSA;
@@ -31,26 +25,14 @@ public class AndroidConfig
extends DefaultConfig { extends DefaultConfig {
static { static {
final Logger log = LoggerFactory.getLogger(AndroidConfig.class); SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider");
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);
}
} }
// don't add ECDSA // don't add ECDSA
protected void initSignatureFactories() { protected void initSignatureFactories() {
setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory()); setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory());
} }
@Override @Override
protected void initRandomFactory(boolean ignored) { protected void initRandomFactory(boolean ignored) {
setRandomFactory(new SingletonRandomFactory(new JCERandom.Factory())); setRandomFactory(new SingletonRandomFactory(new JCERandom.Factory()));

View File

@@ -92,7 +92,7 @@ public class DefaultConfig
} }
protected void initKeyExchangeFactories(boolean bouncyCastleRegistered) { protected void initKeyExchangeFactories(boolean bouncyCastleRegistered) {
if (bouncyCastleRegistered) if (bouncyCastleRegistered) {
setKeyExchangeFactories(new Curve25519SHA256.Factory(), setKeyExchangeFactories(new Curve25519SHA256.Factory(),
new DHGexSHA256.Factory(), new DHGexSHA256.Factory(),
new ECDHNistP.Factory521(), new ECDHNistP.Factory521(),
@@ -101,8 +101,9 @@ public class DefaultConfig
new DHGexSHA1.Factory(), new DHGexSHA1.Factory(),
new DHG14.Factory(), new DHG14.Factory(),
new DHG1.Factory()); new DHG1.Factory());
else } else {
setKeyExchangeFactories(new DHG1.Factory(), new DHGexSHA1.Factory()); setKeyExchangeFactories(new DHG1.Factory(), new DHGexSHA1.Factory());
}
} }
protected void initRandomFactory(boolean bouncyCastleRegistered) { protected void initRandomFactory(boolean bouncyCastleRegistered) {

View File

@@ -15,40 +15,25 @@
*/ */
package net.schmizz.sshj.common; package net.schmizz.sshj.common;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyAgreement; import javax.crypto.KeyAgreement;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException; 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 { 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); 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"; public static final String BOUNCY_CASTLE = "BC";
/* /*
@@ -60,6 +45,42 @@ public class SecurityUtils {
private static Boolean registerBouncyCastle; private static Boolean registerBouncyCastle;
private static boolean registrationDone; 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) public static synchronized Cipher getCipher(String transformation)
throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException {
register(); 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" * 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 * @param key the public key
*
* @return the fingerprint * @return the fingerprint
*
* @see <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00">specification</a> * @see <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00">specification</a>
*/ */
public static String getFingerprint(PublicKey key) { public static String getFingerprint(PublicKey key) {
@@ -98,9 +117,7 @@ public class SecurityUtils {
* Creates a new instance of {@link KeyAgreement} with the given algorithm. * Creates a new instance of {@link KeyAgreement} with the given algorithm.
* *
* @param algorithm key agreement algorithm * @param algorithm key agreement algorithm
*
* @return new instance * @return new instance
*
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws NoSuchProviderException * @throws NoSuchProviderException
*/ */
@@ -117,9 +134,7 @@ public class SecurityUtils {
* Creates a new instance of {@link KeyFactory} with the given algorithm. * Creates a new instance of {@link KeyFactory} with the given algorithm.
* *
* @param algorithm key factory algorithm e.g. RSA, DSA * @param algorithm key factory algorithm e.g. RSA, DSA
*
* @return new instance * @return new instance
*
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws NoSuchProviderException * @throws NoSuchProviderException
*/ */
@@ -136,9 +151,7 @@ public class SecurityUtils {
* Creates a new instance of {@link KeyPairGenerator} with the given algorithm. * Creates a new instance of {@link KeyPairGenerator} with the given algorithm.
* *
* @param algorithm key pair generator algorithm * @param algorithm key pair generator algorithm
*
* @return new instance * @return new instance
*
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws NoSuchProviderException * @throws NoSuchProviderException
*/ */
@@ -155,9 +168,7 @@ public class SecurityUtils {
* Create a new instance of {@link Mac} with the given algorithm. * Create a new instance of {@link Mac} with the given algorithm.
* *
* @param algorithm MAC algorithm * @param algorithm MAC algorithm
*
* @return new instance * @return new instance
*
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws NoSuchProviderException * @throws NoSuchProviderException
*/ */
@@ -174,9 +185,7 @@ public class SecurityUtils {
* Create a new instance of {@link MessageDigest} with the given algorithm. * Create a new instance of {@link MessageDigest} with the given algorithm.
* *
* @param algorithm MessageDigest algorithm name * @param algorithm MessageDigest algorithm name
*
* @return new instance * @return new instance
*
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws NoSuchProviderException * @throws NoSuchProviderException
*/ */
@@ -236,20 +245,16 @@ public class SecurityUtils {
private static void register() { private static void register() {
if (!registrationDone) { if (!registrationDone) {
if (securityProvider == null && (registerBouncyCastle == null || registerBouncyCastle)) if (securityProvider == null && (registerBouncyCastle == null || registerBouncyCastle)) {
// Use an inner class to avoid a strong dependency on BouncyCastle registerSecurityProvider("org.bouncycastle.jce.provider.BouncyCastleProvider");
try { if (securityProvider == null && registerBouncyCastle == null) {
new BouncyCastleRegistration().run(); LOG.info("BouncyCastle not registered, using the default JCE provider");
} catch (Throwable t) { } else if (securityProvider == null) {
if (registerBouncyCastle == null) LOG.error("Failed to register BouncyCastle as the defaut JCE provider");
LOG.info("BouncyCastle not registered, using the default JCE provider"); throw new SSHRuntimeException("Failed to register BouncyCastle as the defaut 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);
}
} }
registrationDone = true; }
} }
registrationDone = true;
} }
} }