OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [security/] [SecureRandom.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* SecureRandom.java --- Secure Random class implementation
2
   Copyright (C) 1999, 2001, 2002, 2003, 2005, 2006
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
package java.security;
40
 
41
import gnu.classpath.SystemProperties;
42
import gnu.java.lang.CPStringBuilder;
43
import gnu.java.security.Engine;
44
import gnu.java.security.action.GetSecurityPropertyAction;
45
import gnu.java.security.jce.prng.SecureRandomAdapter;
46
import gnu.java.security.jce.prng.Sha160RandomSpi;
47
 
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.lang.reflect.InvocationTargetException;
51
import java.net.MalformedURLException;
52
import java.net.URL;
53
import java.util.Enumeration;
54
import java.util.Random;
55
import java.util.logging.Level;
56
import java.util.logging.Logger;
57
 
58
/**
59
 * An interface to a cryptographically secure pseudo-random number
60
 * generator (PRNG). Random (or at least unguessable) numbers are used
61
 * in all areas of security and cryptography, from the generation of
62
 * keys and initialization vectors to the generation of random padding
63
 * bytes.
64
 *
65
 * @author Mark Benvenuto (ivymccough@worldnet.att.net)
66
 * @author Casey Marshall
67
 */
68
public class SecureRandom extends Random
69
{
70
 
71
  // Constants and fields.
72
  // ------------------------------------------------------------------------
73
 
74
  /** Service name for PRNGs. */
75
  private static final String SECURE_RANDOM = "SecureRandom";
76
 
77
  private static final long serialVersionUID = 4940670005562187L;
78
 
79
  //Serialized Field
80
  long counter = 0;             //Serialized
81
  Provider provider = null;
82
  byte[] randomBytes = null;    //Always null
83
  int randomBytesUsed = 0;
84
  SecureRandomSpi secureRandomSpi = null;
85
  byte[] state = null;
86
  private String algorithm;
87
 
88
  private boolean isSeeded = false;
89
 
90
  // Constructors.
91
  // ------------------------------------------------------------------------
92
 
93
  /**
94
     Default constructor for SecureRandom. It constructs a
95
     new SecureRandom by instantating the first SecureRandom
96
     algorithm in the default security provier.
97
 
98
     It is not seeded and should be seeded using setSeed or else
99
     on the first call to getnextBytes it will force a seed.
100
 
101
     It is maintained for backwards compatibility and programs
102
     should use {@link #getInstance(java.lang.String)}.
103
   */
104
  public SecureRandom()
105
  {
106
    Provider[] p = Security.getProviders();
107
 
108
    //Format of Key: SecureRandom.algname
109
    String key;
110
 
111
    String classname = null;
112
    int i;
113
    Enumeration e;
114
    for (i = 0; i < p.length; i++)
115
      {
116
        e = p[i].propertyNames();
117
        while (e.hasMoreElements())
118
          {
119
            key = (String) e.nextElement();
120
            if (key.startsWith("SECURERANDOM."))
121
              {
122
                if ((classname = p[i].getProperty(key)) != null)
123
                  {
124
                    try
125
                      {
126
                        secureRandomSpi = (SecureRandomSpi) Class.
127
                          forName(classname).newInstance();
128
                        provider = p[i];
129
                        algorithm = key.substring(13); // Minus SecureRandom.
130
                        return;
131
                      }
132
                    catch (ThreadDeath death)
133
                      {
134
                        throw death;
135
                      }
136
                    catch (Throwable t)
137
                      {
138
                        // Ignore.
139
                      }
140
                  }
141
              }
142
          }
143
      }
144
 
145
    // Nothing found. Fall back to SHA1PRNG
146
    secureRandomSpi = new Sha160RandomSpi();
147
    algorithm = "Sha160";
148
  }
149
 
150
  /**
151
     A constructor for SecureRandom. It constructs a new
152
     SecureRandom by instantating the first SecureRandom algorithm
153
     in the default security provier.
154
 
155
     It is seeded with the passed function and is useful if the user
156
     has access to hardware random device (like a radiation detector).
157
 
158
     It is maintained for backwards compatibility and programs
159
     should use getInstance.
160
 
161
     @param seed Seed bytes for class
162
   */
163
  public SecureRandom(byte[] seed)
164
  {
165
    this();
166
    setSeed(seed);
167
  }
168
 
169
  /**
170
     A constructor for SecureRandom. It constructs a new
171
     SecureRandom using the specified SecureRandomSpi from
172
     the specified security provier.
173
 
174
     @param secureRandomSpi A SecureRandomSpi class
175
     @param provider A Provider class
176
   */
177
  protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
178
  {
179
    this(secureRandomSpi, provider, "unknown");
180
  }
181
 
182
  /**
183
   * Private constructor called from the getInstance() method.
184
   */
185
  private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider,
186
                       String algorithm)
187
  {
188
    this.secureRandomSpi = secureRandomSpi;
189
    this.provider = provider;
190
    this.algorithm = algorithm;
191
  }
192
 
193
  /**
194
   * Returns an instance of a <code>SecureRandom</code> from the first provider
195
   * that implements it.
196
   *
197
   * @param algorithm The algorithm name.
198
   * @return A new <code>SecureRandom</code> implementing the given algorithm.
199
   * @throws NoSuchAlgorithmException If no installed provider implements the
200
   *           given algorithm.
201
   * @throws IllegalArgumentException if <code>algorithm</code> is
202
   *           <code>null</code> or is an empty string.
203
   */
204
  public static SecureRandom getInstance(String algorithm)
205
      throws NoSuchAlgorithmException
206
  {
207
    Provider[] p = Security.getProviders();
208
    NoSuchAlgorithmException lastException = null;
209
    for (int i = 0; i < p.length; i++)
210
      try
211
        {
212
          return getInstance(algorithm, p[i]);
213
        }
214
      catch (NoSuchAlgorithmException x)
215
        {
216
          lastException = x;
217
        }
218
    if (lastException != null)
219
      throw lastException;
220
    throw new NoSuchAlgorithmException(algorithm);
221
  }
222
 
223
  /**
224
   * Returns an instance of a <code>SecureRandom</code> for the specified
225
   * algorithm from the named provider.
226
   *
227
   * @param algorithm The algorithm name.
228
   * @param provider The provider name.
229
   * @return A new <code>SecureRandom</code> implementing the chosen
230
   *         algorithm.
231
   * @throws NoSuchAlgorithmException If the named provider does not implement
232
   *           the algorithm, or if the implementation cannot be instantiated.
233
   * @throws NoSuchProviderException If no provider named <code>provider</code>
234
   *           is currently installed.
235
   * @throws IllegalArgumentException if either <code>algorithm</code> or
236
   *           <code>provider</code> is <code>null</code> or empty.
237
   */
238
  public static SecureRandom getInstance(String algorithm, String provider)
239
      throws NoSuchAlgorithmException, NoSuchProviderException
240
  {
241
    if (provider == null)
242
      throw new IllegalArgumentException("provider MUST NOT be null");
243
    provider = provider.trim();
244
    if (provider.length() == 0)
245
      throw new IllegalArgumentException("provider MUST NOT be empty");
246
    Provider p = Security.getProvider(provider);
247
    if (p == null)
248
      throw new NoSuchProviderException(provider);
249
    return getInstance(algorithm, p);
250
  }
251
 
252
  /**
253
   * Returns an instance of a <code>SecureRandom</code> for the specified
254
   * algorithm from the given provider.
255
   *
256
   * @param algorithm The <code>SecureRandom</code> algorithm to create.
257
   * @param provider The provider to use.
258
   * @throws NoSuchAlgorithmException If the algorithm cannot be found, or if
259
   *           the class cannot be instantiated.
260
   * @throws IllegalArgumentException if either <code>algorithm</code> or
261
   *           <code>provider</code> is <code>null</code>, or if
262
   *           <code>algorithm</code> is an empty string.
263
   */
264
  public static SecureRandom getInstance(String algorithm, Provider provider)
265
      throws NoSuchAlgorithmException
266
  {
267
    CPStringBuilder sb = new CPStringBuilder("SecureRandom for algorithm [")
268
        .append(algorithm).append("] from provider[")
269
        .append(provider).append("] could not be created");
270
    Throwable cause;
271
    try
272
      {
273
        Object spi = Engine.getInstance(SECURE_RANDOM, algorithm, provider);
274
        return new SecureRandom((SecureRandomSpi) spi, provider, algorithm);
275
      }
276
    catch (InvocationTargetException x)
277
      {
278
        cause = x.getCause();
279
        if (cause instanceof NoSuchAlgorithmException)
280
          throw (NoSuchAlgorithmException) cause;
281
        if (cause == null)
282
          cause = x;
283
      }
284
    catch (ClassCastException x)
285
      {
286
        cause = x;
287
      }
288
    NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
289
    x.initCause(cause);
290
    throw x;
291
  }
292
 
293
  /**
294
     Returns the provider being used by the current SecureRandom class.
295
 
296
     @return The provider from which this SecureRandom was attained
297
   */
298
  public final Provider getProvider()
299
  {
300
    return provider;
301
  }
302
 
303
  /**
304
   * Returns the algorithm name used or "unknown" when the algorithm
305
   * used couldn't be determined (as when constructed by the protected
306
   * 2 argument constructor).
307
   *
308
   * @since 1.5
309
   */
310
  public String getAlgorithm()
311
  {
312
    return algorithm;
313
  }
314
 
315
  /**
316
     Seeds the SecureRandom. The class is re-seeded for each call and
317
     each seed builds on the previous seed so as not to weaken security.
318
 
319
     @param seed seed bytes to seed with
320
   */
321
  public void setSeed(byte[] seed)
322
  {
323
    secureRandomSpi.engineSetSeed(seed);
324
    isSeeded = true;
325
  }
326
 
327
  /**
328
     Seeds the SecureRandom. The class is re-seeded for each call and
329
     each seed builds on the previous seed so as not to weaken security.
330
 
331
     @param seed 8 seed bytes to seed with
332
   */
333
  public void setSeed(long seed)
334
  {
335
    // This particular setSeed will be called by Random.Random(), via
336
    // our own constructor, before secureRandomSpi is initialized.  In
337
    // this case we can't call a method on secureRandomSpi, and we
338
    // definitely don't want to throw a NullPointerException.
339
    // Therefore we test.
340
    if (secureRandomSpi != null)
341
      {
342
        byte[] tmp = { (byte) (0xff & (seed >> 56)),
343
                       (byte) (0xff & (seed >> 48)),
344
                       (byte) (0xff & (seed >> 40)),
345
                       (byte) (0xff & (seed >> 32)),
346
                       (byte) (0xff & (seed >> 24)),
347
                       (byte) (0xff & (seed >> 16)),
348
                       (byte) (0xff & (seed >> 8)),
349
                       (byte) (0xff & seed)
350
        };
351
        secureRandomSpi.engineSetSeed(tmp);
352
        isSeeded = true;
353
      }
354
  }
355
 
356
  /**
357
     Generates a user specified number of bytes. This function
358
     is the basis for all the random functions.
359
 
360
     @param bytes array to store generated bytes in
361
   */
362
  public void nextBytes(byte[] bytes)
363
  {
364
    if (!isSeeded)
365
      setSeed(getSeed(32));
366
    randomBytesUsed += bytes.length;
367
    counter++;
368
    secureRandomSpi.engineNextBytes(bytes);
369
  }
370
 
371
  /**
372
     Generates an integer containing the user specified
373
     number of random bits. It is right justified and padded
374
     with zeros.
375
 
376
     @param numBits number of random bits to get, 0 <= numBits <= 32;
377
 
378
     @return the random bits
379
   */
380
  protected final int next(int numBits)
381
  {
382
    if (numBits == 0)
383
      return 0;
384
 
385
    byte[] tmp = new byte[(numBits + 7) / 8];
386
    this.nextBytes(tmp);
387
    int ret = 0;
388
    for (int i = 0; i < tmp.length; i++)
389
      ret |= (tmp[i] & 0xFF) << (8 * i);
390
 
391
    long mask = (1L << numBits) - 1;
392
    return (int) (ret & mask);
393
  }
394
 
395
  /**
396
     Returns the given number of seed bytes. This method is
397
     maintained only for backwards capability.
398
 
399
     @param numBytes number of seed bytes to get
400
 
401
     @return an array containing the seed bytes
402
   */
403
  public static byte[] getSeed(int numBytes)
404
  {
405
    return SecureRandomAdapter.getSeed(numBytes);
406
  }
407
 
408
  /**
409
     Returns the specified number of seed bytes.
410
 
411
     @param numBytes number of seed bytes to get
412
 
413
     @return an array containing the seed bytes
414
   */
415
  public byte[] generateSeed(int numBytes)
416
  {
417
    return secureRandomSpi.engineGenerateSeed(numBytes);
418
  }
419
 
420
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.