/* ====================================================================
* The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
*
* Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by Jcorporate Ltd.
* (http://www.jcorporate.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. "Jcorporate" and product names such as "Expresso" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written permission,
* please contact info@jcorporate.com.
*
* 5. Products derived from this software may not be called "Expresso",
* or other Jcorporate product names; nor may "Expresso" or other
* Jcorporate product names appear in their name, without prior
* written permission of Jcorporate Ltd.
*
* 6. No product derived from this software may compete in the same
* market space, i.e. framework, without prior written permission
* of Jcorporate Ltd. For written permission, please contact
* partners@jcorporate.com.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jcorporate Ltd. Contributions back
* to the project(s) are encouraged when you make modifications.
* Please send them to support@jcorporate.com. For more information
* on Jcorporate Ltd. and its products, please see
* <http://www.jcorporate.com/>.
*
* Portions of this software are based upon other open source
* products and are subject to their respective licenses.
*/
package com.jcorporate.expresso.core.security;
import com.jcorporate.expresso.core.misc.ByteArrayCounter;
import com.jcorporate.expresso.core.misc.ConfigManager;
import com.jcorporate.expresso.kernel.ComponentLifecycle;
import com.jcorporate.expresso.kernel.Configuration;
import com.jcorporate.expresso.kernel.exception.ChainedException;
import com.jcorporate.expresso.kernel.exception.ConfigurationException;
/**
* CryptoManager.java
* <p/>
* Singleton Class that acts as a facade for managing if strong or weak crypto
* is desired.
* </p>
* Copyright 2000-2002 Jcorporate Ltd.
*
* @author Michael Rimov
* @since Expresso 3.0
*/
public class CryptoManager extends com.jcorporate.expresso.kernel.ComponentBase implements ComponentLifecycle {
//static final private String defaultPW = "Jcorporate Rocks";
static final private String thisClass = "com.jcorporate.expresso.core.security.CryptoManager";
static private CryptoManager theManager = null;
static protected ByteArrayCounter ivCounter = new ByteArrayCounter(8);
protected AbstractRandomNumber randomGenerator = null;
protected AbstractStringEncryption stringEncryptor = null;
protected StringHash stringHash = null;
boolean initialized;
String encryptMode;
/**
* Flag for string cryptography
*/
boolean strongCrypto = false;
/**
* Passphrase
*/
private String cryptoKey;
private String randomSeed;
/**
* Do not call this constructor directly. Use getInstance() instead.
* This is public ONLY so that it can be instantiated by the test program.
*/
public CryptoManager() {
} /* CryptoManager() */
/**
* Singleton Generator. Call to get an instance of the Crypto Manager<p>
* <B>Please Note</B> If strong encryption is used, this class may take quite
* some time in initializing due to the nature of generating a default seed for
* the crypto-strength random number generator.
*
* @return the ony and only instance of the Crypto Manager;
* @throws ChainedException If there is a problem instantiating the crypto classes
*/
public static synchronized CryptoManager getInstance()
throws ChainedException {
if (theManager == null) {
theManager = new CryptoManager();
boolean strongCrypto = false;
strongCrypto = ConfigManager.getConfig().strongCrypto();
theManager.setEncryptMode(ConfigManager.getConfig().getEncryptMode());
theManager.setCryptoKey(ConfigManager.getConfig().getCryptoKey());
theManager.setRandomSeed(ConfigManager.getConfigDir());
theManager.setStrongCrypto(strongCrypto);
//Do we use weak obfuscation methods?
if (!strongCrypto) {
theManager.loadClasses(false);
} else {
theManager.loadClasses(true);
}
}
return theManager;
} /* getInstance() */
/**
* Method removes all static entries.
*/
public synchronized void destroy() {
stringEncryptor.destroy();
randomGenerator = null;
stringHash = null;
stringEncryptor = null;
theManager = null;
}
/**
* Returns whether the crypto manager is using strong cryptography or not.
*
* @return true if a strong cryptographic provider is included
*/
public synchronized boolean isUsingStrongCrypto() {
return strongCrypto;
}
/**
* Returns an instantiated subclass of AbstractRandomNumber depending if
* strong or weak crypto is desired.
*
* @return a random number generator
* @see com.jcorporate.expresso.core.security.AbstractRandomNumber
* @see com.jcorporate.expresso.core.security.weakencryption.RandomNumber
* @see com.jcorporate.expresso.core.security.strongencryption.RandomNumber
*/
public synchronized AbstractRandomNumber getRandomGenerator() {
return randomGenerator;
} /* getRandomGenerator() */
/**
* Factory method that returns an instantiated subclass of
* <code>AbstractStringEncryption</code> depending of strong
* or weak crypto is desired.
*
* @return A string encryption concrete class.
* @see com.jcorporate.expresso.core.security.AbstractStringEncryption
* @see com.jcorporate.expresso.core.security.weakencryption.StringEncryption
* @see com.jcorporate.expresso.core.security.strongencryption.StringEncryption
*/
public synchronized AbstractStringEncryption getStringEncryption() {
return stringEncryptor;
} /* getStringEncryption() */
/**
* Factory method that returns an instantiated subclass of
* <code>AbstractStringHash</code> depending of strong
* or weak crypto is desired.
*
* @return An instantiated String Hashing class
* @see com.jcorporate.expresso.core.security.StringHash
*/
public synchronized StringHash getStringHash() {
return stringHash;
} /* getStringHash() */
/**
* Loads the appropriate crypto classes. Also is split off from the constructor
* for testing purposes.
*
* @param useStrongCrypto Set to true if we desire to load the strong
* cryptographic classes.
* @throws ChainedException upon error loading the classes.
*/
public synchronized void loadClasses(boolean useStrongCrypto)
throws ChainedException {
String packageName;
final String myName = thisClass + ".loadClasses";
strongCrypto = useStrongCrypto;
//Do we use weak obfuscation methods instead?
if (useStrongCrypto == false) {
packageName = "com.jcorporate.expresso.core.security.weakencryption";
} else {
//No
packageName = "com.jcorporate.expresso.core.security.strongencryption";
}
//Load up the classes
try {
randomGenerator = (AbstractRandomNumber) Class.forName(packageName +
".RandomNumber").newInstance();
stringEncryptor = (AbstractStringEncryption) Class.forName(packageName +
".StringEncryption").newInstance();
stringHash = new StringHash();
randomGenerator.setCryptoManager(this);
stringEncryptor.setCryptoManager(this);
stringHash.setCryptoManager(this);
stringEncryptor.init();
randomGenerator.init();
} catch (ClassNotFoundException ex) {
throw new ChainedException(myName +
" Unable to load crypto class in package " +
packageName, ex);
} catch (IllegalAccessException ex) {
throw new ChainedException(myName + ":Package " + packageName, ex);
} catch (InstantiationException ex) {
throw new ChainedException(myName +
" Unable to instantiate a cryto class in package " +
packageName, ex);
} catch (ChainedException e) {
throw e;
} catch (Exception e) {
throw new ChainedException(myName +
":Unable to load classes for crypto package " +
packageName, e);
}
}
public synchronized void initialize() {
theManager = this;
}
/**
* Configure the Cryptographic manager
*
* @param newConfig the new configuration bean to configure with
* @throws ConfigurationException upon configuration error
*/
public synchronized void configure(Configuration newConfig) throws ConfigurationException {
Boolean strongCrypto = (Boolean) newConfig.get("StrongCrypto");
this.setStrongCrypto(strongCrypto.booleanValue());
this.setEncryptMode((String) newConfig.get("EncryptMode"));
this.setCryptoKey((String) newConfig.get("CryptoKey"));
this.setRandomSeed((String) newConfig.get("RandomSeed"));
//Do we use weak obfuscation methods?
try {
if (!strongCrypto.booleanValue()) {
theManager.loadClasses(false);
} else {
theManager.loadClasses(true);
}
} catch (ChainedException ex) {
throw new ConfigurationException("Error loading cryptographic manager.", ex);
}
}
/**
* Reconfigure lifecycle event. Destroys itself and reconstructs with
* the new configuration
*
* @param newConfig the configuration data to reconfigure with.
*/
public synchronized void reconfigure(Configuration newConfig) throws ConfigurationException {
destroy();
setStrongCrypto(false);
setEncryptMode(null);
setCryptoKey(null);
setRandomSeed(null);
configure(newConfig);
}
public synchronized boolean isStrongCrypto() {
return strongCrypto;
}
public synchronized void setStrongCrypto(boolean strongCrypto) {
this.strongCrypto = strongCrypto;
}
public synchronized String getEncryptMode() {
return encryptMode;
}
public synchronized void setEncryptMode(String encryptMode) {
this.encryptMode = encryptMode;
}
public boolean isInitialized() {
return initialized;
}
public void setCryptoKey(String cryptoKey) {
this.cryptoKey = cryptoKey;
}
public String getCryptoKey() {
return cryptoKey;
}
public void setRandomSeed(String randomSeed) {
this.randomSeed = randomSeed;
}
public String getRandomSeed() {
return randomSeed;
}
} /* CryptoManager */
|