/**************************************************************************
* Copyright (c) 2001 by Punch Telematix. 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. Neither the name of Punch Telematix nor the names of *
* other contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission.*
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS 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 PUNCH TELEMATIX OR OTHER 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. *
**************************************************************************/
package java.security;
import java.util.Enumeration;
import java.util.Random;
public class SecureRandom extends Random {
private static final long serialVersionUID = 4940670005562187L;
public static SecureRandom getInstance(String algorithm) throws NoSuchAlgorithmException {
SecurityAction action = new SecurityAction(algorithm, "SecureRandom.");
return new SecureRandom((SecureRandomSpi)action.spi, action.provider);
}
public static SecureRandom getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
SecurityAction action = new SecurityAction(algorithm, provider, "SecureRandom.");
return new SecureRandom((SecureRandomSpi)action.spi, action.provider);
}
public static SecureRandom getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
SecurityAction action = new SecurityAction(algorithm, provider, "SecureRandom.");
return new SecureRandom((SecureRandomSpi)action.spi, provider);
}
public static byte[] getSeed(int numBytes){
return new SecureRandom().generateSeed(numBytes);
}
/**
** dictated by the Serialized From ...
*/
private long counter;
private MessageDigest digest;
private Provider provider;
private byte[] randomBytes;
private int randomBytesUsed;
private SecureRandomSpi secureRandomSpi;
private byte[] state;
public SecureRandom(){
Provider[] p = Security.getProviders();
for (int i=0 ; i < p.length ; i++){
Provider prov = p[i];
Enumeration e = prov.propertyNames();
while(e.hasMoreElements()){
String key = (String)e.nextElement();
if(key.startsWith("SecureRandom.")){
String classname = prov.getProperty(key);
try {
secureRandomSpi = (SecureRandomSpi)Class.forName(classname, true, SecurityAction.getClassLoader(prov)).newInstance();
provider = prov;
i = p.length;
break;
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
if(secureRandomSpi == null){
throw new RuntimeException("couldn't find a SecureRandom");
}
}
public SecureRandom(byte[] seed){
this();
setSeed(seed);
}
protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider){
this.secureRandomSpi = secureRandomSpi;
this.provider = provider;
}
public byte[] generateSeed(int numBytes){
return secureRandomSpi.engineGenerateSeed(numBytes);
}
public final Provider getProvider(){
return provider;
}
protected final int next(int numBits){
if (numBits <= 0 || numBits > 32){
throw new IllegalArgumentException();
}
int bts = (numBits-1)/8+1;
byte [] bytes = new byte[bts];
nextBytes(bytes);
if (bts > 0){
int mod = (0x0ff >> (8 - ( numBits % 8 )));
if(mod > 0) {
bytes[bts-1] = (byte)((0xff & (char) bytes[bts-1]) & mod);
}
}
int next = 0;
for (int i=0 ; i < bts ; i++){
next = (next << 8) + (0x0ff & (char)bytes[i]);
}
return next;
}
public void nextBytes(byte[] bytes){
secureRandomSpi.engineNextBytes(bytes);
}
public void setSeed(byte[] seed){
secureRandomSpi.engineSetSeed(seed);
}
public void setSeed(long seed){
//if we come into the super() this method gets called
if(secureRandomSpi != null){
byte[] bytes = new byte[8];
for (int i=0 ; i < 8 ; i++){
bytes[i] = (byte)seed;
seed = (seed >> 8);
}
setSeed(bytes);
}
}
}