Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / security / SecureRandom.java
blob5d200383843bdd08b32eb4fd83ed833576587a42
1 /* SecureRandom.java --- Secure Random class implementation
2 Copyright (C) 1999, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.security;
40 import gnu.java.security.Engine;
42 import java.util.Enumeration;
43 import java.util.Random;
45 /**
46 * An interface to a cryptographically secure pseudo-random number
47 * generator (PRNG). Random (or at least unguessable) numbers are used
48 * in all areas of security and cryptography, from the generation of
49 * keys and initialization vectors to the generation of random padding
50 * bytes.
52 * @author Mark Benvenuto (ivymccough@worldnet.att.net)
53 * @author Casey Marshall
55 public class SecureRandom extends Random
58 // Constants and fields.
59 // ------------------------------------------------------------------------
61 /** Service name for PRNGs. */
62 private static final String SECURE_RANDOM = "SecureRandom";
64 private static final long serialVersionUID = 4940670005562187L;
66 //Serialized Field
67 long counter = 0; //Serialized
68 Provider provider = null;
69 byte[] randomBytes = null; //Always null
70 int randomBytesUsed = 0;
71 SecureRandomSpi secureRandomSpi = null;
72 byte[] state = null;
74 // Constructors.
75 // ------------------------------------------------------------------------
77 /**
78 Default constructor for SecureRandom. It constructs a
79 new SecureRandom by instantating the first SecureRandom
80 algorithm in the default security provier.
82 It is not seeded and should be seeded using setSeed or else
83 on the first call to getnextBytes it will force a seed.
85 It is maintained for backwards compatibility and programs
86 should use {@link #getInstance(java.lang.String)}.
88 public SecureRandom()
90 Provider[] p = Security.getProviders();
92 //Format of Key: SecureRandom.algname
93 String key;
95 String classname = null;
96 int i;
97 Enumeration e;
98 for (i = 0; i < p.length; i++)
100 e = p[i].propertyNames();
101 while (e.hasMoreElements())
103 key = (String) e.nextElement();
104 if (key.startsWith("SECURERANDOM."))
106 if ((classname = p[i].getProperty(key)) != null)
110 secureRandomSpi = (SecureRandomSpi) Class.
111 forName(classname).newInstance();
112 provider = p[i];
113 return;
115 catch (ThreadDeath death)
117 throw death;
119 catch (Throwable t)
121 // Ignore.
128 // Nothing found. Fall back to SHA1PRNG
129 secureRandomSpi = new gnu.java.security.provider.SHA1PRNG();
133 A constructor for SecureRandom. It constructs a new
134 SecureRandom by instantating the first SecureRandom algorithm
135 in the default security provier.
137 It is seeded with the passed function and is useful if the user
138 has access to hardware random device (like a radiation detector).
140 It is maintained for backwards compatibility and programs
141 should use getInstance.
143 @param seed Seed bytes for class
145 public SecureRandom(byte[] seed)
147 this();
148 setSeed(seed);
152 A constructor for SecureRandom. It constructs a new
153 SecureRandom using the specified SecureRandomSpi from
154 the specified security provier.
156 @param secureRandomSpi A SecureRandomSpi class
157 @param provider A Provider class
159 protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
161 this.secureRandomSpi = secureRandomSpi;
162 this.provider = provider;
165 // Class methods.
166 // ------------------------------------------------------------------------
169 * Returns an instance of a SecureRandom. It creates the class from
170 * the first provider that implements it.
172 * @param algorithm The algorithm name.
173 * @return A new SecureRandom implementing the given algorithm.
174 * @throws NoSuchAlgorithmException If no installed provider implements
175 * the given algorithm.
177 public static SecureRandom getInstance(String algorithm)
178 throws NoSuchAlgorithmException
180 Provider[] p = Security.getProviders();
182 for (int i = 0; i < p.length; i++)
186 return getInstance(algorithm, p[i]);
188 catch (NoSuchAlgorithmException e)
190 // Ignore.
194 // None found.
195 throw new NoSuchAlgorithmException(algorithm);
199 * Returns an instance of a SecureRandom. It creates the class
200 * for the specified algorithm from the named provider.
202 * @param algorithm The algorithm name.
203 * @param provider The provider name.
204 * @return A new SecureRandom implementing the chosen algorithm.
205 * @throws NoSuchAlgorithmException If the named provider does not implement
206 * the algorithm, or if the implementation cannot be
207 * instantiated.
208 * @throws NoSuchProviderException If no provider named
209 * <code>provider</code> is currently installed.
210 * @throws IllegalArgumentException If <code>provider</code> is null
211 * or is empty.
213 public static SecureRandom getInstance(String algorithm, String provider)
214 throws NoSuchAlgorithmException, NoSuchProviderException
216 if (provider == null || provider.length() == 0)
217 throw new IllegalArgumentException("Illegal provider");
219 Provider p = Security.getProvider(provider);
220 if (p == null)
221 throw new NoSuchProviderException(provider);
223 return getInstance(algorithm, p);
227 * Returns an instance of a SecureRandom. It creates the class for
228 * the specified algorithm from the given provider.
230 * @param algorithm The SecureRandom algorithm to create.
231 * @param provider The provider to get the instance from.
232 * @throws NoSuchAlgorithmException If the algorithm cannot be found, or
233 * if the class cannot be instantiated.
234 * @throws IllegalArgumentException If <code>provider</code> is null.
236 public static SecureRandom getInstance(String algorithm, Provider provider)
237 throws NoSuchAlgorithmException
239 if (provider == null)
240 throw new IllegalArgumentException("Illegal provider");
243 return new SecureRandom((SecureRandomSpi)
244 Engine.getInstance(SECURE_RANDOM, algorithm, provider),
245 provider);
247 catch (java.lang.reflect.InvocationTargetException ite)
249 throw new NoSuchAlgorithmException(algorithm);
251 catch (ClassCastException cce)
253 throw new NoSuchAlgorithmException(algorithm);
257 // Instance methods.
258 // ------------------------------------------------------------------------
261 Returns the provider being used by the current SecureRandom class.
263 @return The provider from which this SecureRandom was attained
265 public final Provider getProvider()
267 return provider;
271 Seeds the SecureRandom. The class is re-seeded for each call and
272 each seed builds on the previous seed so as not to weaken security.
274 @param seed seed bytes to seed with
276 public void setSeed(byte[] seed)
278 secureRandomSpi.engineSetSeed(seed);
282 Seeds the SecureRandom. The class is re-seeded for each call and
283 each seed builds on the previous seed so as not to weaken security.
285 @param seed 8 seed bytes to seed with
287 public void setSeed(long seed)
289 // This particular setSeed will be called by Random.Random(), via
290 // our own constructor, before secureRandomSpi is initialized. In
291 // this case we can't call a method on secureRandomSpi, and we
292 // definitely don't want to throw a NullPointerException.
293 // Therefore we test.
294 if (secureRandomSpi != null)
296 byte[] tmp = { (byte) (0xff & (seed >> 56)),
297 (byte) (0xff & (seed >> 48)),
298 (byte) (0xff & (seed >> 40)),
299 (byte) (0xff & (seed >> 32)),
300 (byte) (0xff & (seed >> 24)),
301 (byte) (0xff & (seed >> 16)),
302 (byte) (0xff & (seed >> 8)),
303 (byte) (0xff & seed)
305 secureRandomSpi.engineSetSeed(tmp);
310 Generates a user specified number of bytes. This function
311 is the basis for all the random functions.
313 @param bytes array to store generated bytes in
315 public void nextBytes(byte[] bytes)
317 randomBytesUsed += bytes.length;
318 counter++;
319 secureRandomSpi.engineNextBytes(bytes);
323 Generates an integer containing the user specified
324 number of random bits. It is right justified and padded
325 with zeros.
327 @param numBits number of random bits to get, 0 <= numBits <= 32;
329 @return the random bits
331 protected final int next(int numBits)
333 if (numBits == 0)
334 return 0;
336 byte[] tmp = new byte[numBits / 8 + (1 * (numBits % 8))];
338 secureRandomSpi.engineNextBytes(tmp);
339 randomBytesUsed += tmp.length;
340 counter++;
342 int ret = 0;
344 for (int i = 0; i < tmp.length; i++)
345 ret |= (tmp[i] & 0xFF) << (8 * i);
347 long mask = (1L << numBits) - 1;
348 return (int) (ret & mask);
352 Returns the given number of seed bytes. This method is
353 maintained only for backwards capability.
355 @param numBytes number of seed bytes to get
357 @return an array containing the seed bytes
359 public static byte[] getSeed(int numBytes)
361 byte[] tmp = new byte[numBytes];
363 new Random().nextBytes(tmp);
364 return tmp;
365 //return secureRandomSpi.engineGenerateSeed( numBytes );
369 Returns the specified number of seed bytes.
371 @param numBytes number of seed bytes to get
373 @return an array containing the seed bytes
375 public byte[] generateSeed(int numBytes)
377 return secureRandomSpi.engineGenerateSeed(numBytes);