[kaffe] CVS kaffe (robilad): Replaced SecureRandom by implementation from GNU Classpath

Kaffe CVS cvs-commits at kaffe.org
Wed Sep 22 17:26:10 PDT 2004


PatchSet 5210 
Date: 2004/09/23 00:21:56
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
Replaced SecureRandom by implementation from GNU Classpath

2004-09-22  Dalibor Topic  <robilad at kaffe.org>

        * libraries/javalib/gnu/java/security/provider/SHA1PRNG.java:
        New file, taken from GNU Classpath.

        * libraries/javalib/Makefile.am,
        libraries/javalib/Makefile.in,
        libraries/javalib/all.files:
        Regenerated.

        * libraries/javalib/java/security/SecureRandom.java:
        Replaced by implementation from GNU Classpath.

Members: 
	ChangeLog:1.2765->1.2766 
	libraries/javalib/Makefile.am:1.235->1.236 
	libraries/javalib/Makefile.in:1.315->1.316 
	libraries/javalib/all.files:1.23->1.24 
	libraries/javalib/gnu/java/security/provider/SHA1PRNG.java:INITIAL->1.1 
	libraries/javalib/java/security/SecureRandom.java:1.5->1.6 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2765 kaffe/ChangeLog:1.2766
--- kaffe/ChangeLog:1.2765	Wed Sep 22 21:30:41 2004
+++ kaffe/ChangeLog	Thu Sep 23 00:21:56 2004
@@ -1,5 +1,18 @@
 2004-09-22  Dalibor Topic  <robilad at kaffe.org>
 
+	* libraries/javalib/gnu/java/security/provider/SHA1PRNG.java:
+	New file, taken from GNU Classpath.
+
+	* libraries/javalib/Makefile.am,
+	libraries/javalib/Makefile.in,
+	libraries/javalib/all.files:
+	Regenerated.
+
+	* libraries/javalib/java/security/SecureRandom.java:
+        Replaced by implementation from GNU Classpath.
+
+2004-09-22  Dalibor Topic  <robilad at kaffe.org>
+
 	* libraries/javalib/java/security/SecureRandomSpi.java:
         Replaced by implementation from GNU Classpath.
 
Index: kaffe/libraries/javalib/Makefile.am
diff -u kaffe/libraries/javalib/Makefile.am:1.235 kaffe/libraries/javalib/Makefile.am:1.236
--- kaffe/libraries/javalib/Makefile.am:1.235	Tue Sep 21 16:27:07 2004
+++ kaffe/libraries/javalib/Makefile.am	Thu Sep 23 00:21:58 2004
@@ -1245,7 +1245,8 @@
 	gnu/java/security/der/DERValue.java \
 	gnu/java/security/der/DERWriter.java
 gnu_java_security_provider_SRCS = \
-	gnu/java/security/provider/DefaultPolicy.java
+	gnu/java/security/provider/DefaultPolicy.java \
+	gnu/java/security/provider/SHA1PRNG.java
 gnu_java_security_x509_SRCS = \
 	gnu/java/security/x509/X500DistinguishedName.java
 gnu_java_text_SRCS = \
Index: kaffe/libraries/javalib/Makefile.in
diff -u kaffe/libraries/javalib/Makefile.in:1.315 kaffe/libraries/javalib/Makefile.in:1.316
--- kaffe/libraries/javalib/Makefile.in:1.315	Tue Sep 21 16:27:07 2004
+++ kaffe/libraries/javalib/Makefile.in	Thu Sep 23 00:21:59 2004
@@ -1674,7 +1674,8 @@
 	gnu/java/security/der/DERWriter.java
 
 gnu_java_security_provider_SRCS = \
-	gnu/java/security/provider/DefaultPolicy.java
+	gnu/java/security/provider/DefaultPolicy.java \
+	gnu/java/security/provider/SHA1PRNG.java
 
 gnu_java_security_x509_SRCS = \
 	gnu/java/security/x509/X500DistinguishedName.java
Index: kaffe/libraries/javalib/all.files
diff -u kaffe/libraries/javalib/all.files:1.23 kaffe/libraries/javalib/all.files:1.24
--- kaffe/libraries/javalib/all.files:1.23	Tue Sep 21 16:27:08 2004
+++ kaffe/libraries/javalib/all.files	Thu Sep 23 00:22:01 2004
@@ -842,6 +842,7 @@
 gnu/java/security/der/DERValue.java
 gnu/java/security/der/DERWriter.java
 gnu/java/security/provider/DefaultPolicy.java
+gnu/java/security/provider/SHA1PRNG.java
 gnu/java/security/x509/X500DistinguishedName.java
 gnu/java/text/AttributedFormatBuffer.java
 gnu/java/text/BaseBreakIterator.java
===================================================================
Checking out kaffe/libraries/javalib/gnu/java/security/provider/SHA1PRNG.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/gnu/java/security/provider/SHA1PRNG.java,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/gnu/java/security/provider/SHA1PRNG.java	Thu Sep 23 00:26:09 2004
@@ -0,0 +1,126 @@
+/* SHA1PRNG.java --- Secure Random SPI SHA1PRNG
+   Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.provider;
+
+import java.util.Random;
+import java.security.SecureRandomSpi;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.io.Serializable;
+
+public class SHA1PRNG extends SecureRandomSpi implements Serializable
+{
+  MessageDigest digest;
+  byte seed[];
+  byte data[];
+  int seedpos;
+  int datapos;
+  private boolean seeded = false; // set to true when we seed this
+
+  public SHA1PRNG()
+  {
+    try {
+      digest = MessageDigest.getInstance("SHA");
+    } catch ( NoSuchAlgorithmException nsae) {
+//      System.out.println("Failed to find SHA Message Digest: " + nsae);
+//      nsae.printStackTrace();
+      throw new InternalError ("no SHA implementation found");
+    }
+
+    seed = new byte[20];
+    seedpos = 0;
+    data = new byte[40];
+    datapos = 20;  // try to force hashing a first block
+  }
+
+  public void engineSetSeed(byte[] seed)
+  {
+    for(int i = 0; i < seed.length; i++)
+      this.seed[seedpos++ % 20] ^= seed[i];
+    seedpos %= 20;
+
+  }
+
+  public void engineNextBytes(byte[] bytes)
+  {
+    ensureIsSeeded ();
+    int loc = 0;
+    while (loc < bytes.length)
+      {
+	int copy = Math.min (bytes.length - loc, 20 - datapos);
+
+	if (copy > 0)
+	  {
+	    System.arraycopy (data, datapos, bytes, loc, copy);
+	    datapos += copy;
+	    loc += copy;
+	  }
+	else
+	  {
+	    // No data ready for copying, so refill our buffer.
+	    System.arraycopy( seed, 0, data, 20, 20);
+	    byte[] digestdata = digest.digest( data );
+	    System.arraycopy( digestdata, 0, data, 0, 20);
+	    datapos = 0;
+	  }
+      }
+  }
+
+  public byte[] engineGenerateSeed(int numBytes)
+  {
+    byte tmp[] = new byte[numBytes];
+	
+    engineNextBytes( tmp );
+    return tmp;
+  }
+
+  private void ensureIsSeeded()
+  {
+    if (!seeded)
+      {
+        new Random(0L).nextBytes(seed);
+
+        byte[] digestdata = digest.digest(data);
+        System.arraycopy(digestdata, 0, data, 0, 20);
+
+        seeded = true;
+      }
+  }
+
+}
Index: kaffe/libraries/javalib/java/security/SecureRandom.java
diff -u kaffe/libraries/javalib/java/security/SecureRandom.java:1.5 kaffe/libraries/javalib/java/security/SecureRandom.java:1.6
--- kaffe/libraries/javalib/java/security/SecureRandom.java:1.5	Mon Oct 27 19:33:04 2003
+++ kaffe/libraries/javalib/java/security/SecureRandom.java	Thu Sep 23 00:22:02 2004
@@ -1,100 +1,371 @@
-/*
- * Java core library component.
- *
- * Copyright (c) 1999
- *      Transvirtual Technologies, Inc.  All rights reserved.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file.
- */
+/* SecureRandom.java --- Secure Random class implementation
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
 
 package java.security;
 
+import gnu.java.security.Engine;
+
+import java.util.Enumeration;
 import java.util.Random;
 
-public class SecureRandom extends Random {
+/**
+ * An interface to a cryptographically secure pseudo-random number
+ * generator (PRNG). Random (or at least unguessable) numbers are used
+ * in all areas of security and cryptography, from the generation of
+ * keys and initialization vectors to the generation of random padding
+ * bytes.
+ *
+ * @author Mark Benvenuto <ivymccough at worldnet.att.net>
+ * @author Casey Marshall
+ */
+public class SecureRandom extends Random
+{
 
-static final String ENGINE_CLASS = "SecureRandom";
+  // Constants and fields.
+  // ------------------------------------------------------------------------
 
-private final Provider provider;
-private final SecureRandomSpi engine;
+  /** Service name for PRNGs. */
+  private static final String SECURE_RANDOM = "SecureRandom";
 
-public SecureRandom() { 
-	try {
-		Security.Engine e = Security.getCryptInstance(ENGINE_CLASS);
-		provider = e.getProvider();
-		engine = (SecureRandomSpi)e.getEngine();
-	}
-	catch (NoSuchAlgorithmException e) {
-		throw new Error("no " + ENGINE_CLASS + " found");
-	}
-}
-
-public SecureRandom(byte[] seed){
-	this();
-	setSeed(seed);
-}
-
-protected SecureRandom(SecureRandomSpi engine, Provider provider) {
-	this.engine = engine;
-	this.provider = provider;
-}
-
-public static SecureRandom getInstance(String alg)
-		throws NoSuchAlgorithmException {
-	Security.Engine e = Security.getCryptInstance(ENGINE_CLASS, alg);
-	return new SecureRandom((SecureRandomSpi)e.getEngine(),
-				e.getProvider());
-}
-
-public static SecureRandom getInstance(String alg, String prov) 
-		throws NoSuchAlgorithmException, NoSuchProviderException {
-	Security.Engine e = Security.getCryptInstance( ENGINE_CLASS, alg, prov);
-	return new SecureRandom((SecureRandomSpi)e.getEngine(),
-				e.getProvider());
-}
-
-public final Provider getProvider() {
-	return provider;
-}
-
-public void setSeed(byte[] seed) {
-	if (engine != null) {
-		engine.engineSetSeed(seed);
-	}
-}
-
-public void setSeed(long seed) {
-	byte[] nseed = new byte[8];
-	for (int i = 0; i < 8; i++) {
-		nseed[i] = (byte)(seed >> (i * 8));
-	}
-	setSeed(nseed);
-}
-
-public void nextBytes(byte[] bytes) {
-	engine.engineNextBytes(bytes);
-}
-
-protected final int next(int numBits) {
-	byte[] res = new byte[(numBits + 7) / 8];
-	int lpc, retval = 0;
-	
-	nextBytes(res);
-	for( lpc = res.length - 1; lpc >= 0; lpc-- )
-	{
-		retval |= ((res[res.length - lpc - 1] & 0xFF) << (8 * lpc));
-	}
-	return retval >> (res.length * 8 - numBits);
-
-}
-
-public static byte[] getSeed(int numBytes) {
-	return new SecureRandom().getSeed(numBytes);
-}
-
-public byte[] generateSeed(int numBytes) {
-	return engine.engineGenerateSeed(numBytes);
-}
+  private static final long serialVersionUID = 4940670005562187L;
+
+  //Serialized Field
+  long counter = 0;		//Serialized
+  Provider provider = null;
+  byte[] randomBytes = null;	//Always null
+  int randomBytesUsed = 0;
+  SecureRandomSpi secureRandomSpi = null;
+  byte[] state = null;
+
+  // Constructors.
+  // ------------------------------------------------------------------------
+
+  /**
+     Default constructor for SecureRandom. It constructs a 
+     new SecureRandom by instantating the first SecureRandom 
+     algorithm in the default security provier. 
+
+     It is not seeded and should be seeded using setSeed or else
+     on the first call to getnextBytes it will force a seed.
+
+     It is maintained for backwards compatibility and programs
+     should use {@link #getInstance(java.lang.String)}.
+   */
+  public SecureRandom()
+  {
+    Provider p[] = Security.getProviders();
+
+    //Format of Key: SecureRandom.algname
+    String key;
+
+    String classname = null;
+    int i;
+    Enumeration e;
+    for (i = 0; i < p.length; i++)
+      {
+        e = p[i].propertyNames();
+        while (e.hasMoreElements())
+          {
+            key = (String) e.nextElement();
+            if (key.startsWith("SECURERANDOM."))
+              {
+                if ((classname = p[i].getProperty(key)) != null)
+                  {
+                    try
+                      {
+                        secureRandomSpi = (SecureRandomSpi) Class.
+                          forName(classname).newInstance();
+                        provider = p[i];
+                        return;
+                      }
+                    catch (Throwable ignore) { }
+                  }
+              }
+          }
+      }
+
+    // Nothing found. Fall back to SHA1PRNG
+    secureRandomSpi = new gnu.java.security.provider.SHA1PRNG();
+  }
+
+  /**
+     A constructor for SecureRandom. It constructs a new 
+     SecureRandom by instantating the first SecureRandom algorithm 
+     in the default security provier. 
+
+     It is seeded with the passed function and is useful if the user
+     has access to hardware random device (like a radiation detector).
+
+     It is maintained for backwards compatibility and programs
+     should use getInstance.
+
+     @param seed Seed bytes for class
+   */
+  public SecureRandom(byte[] seed)
+  {
+    this();
+    setSeed(seed);
+  }
+
+  /**
+     A constructor for SecureRandom. It constructs a new 
+     SecureRandom using the specified SecureRandomSpi from
+     the specified security provier. 
+
+     @param secureRandomSpi A SecureRandomSpi class
+     @param provider A Provider class
+   */
+  protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
+  {
+    this.secureRandomSpi = secureRandomSpi;
+    this.provider = provider;
+  }
+
+  // Class methods.
+  // ------------------------------------------------------------------------
+
+  /**
+   * Returns an instance of a SecureRandom. It creates the class from
+   * the first provider that implements it.
+   *
+   * @param algorithm The algorithm name.
+   * @return A new SecureRandom implementing the given algorithm.
+   * @throws NoSuchAlgorithmException If no installed provider implements
+   *         the given algorithm.
+   */
+  public static SecureRandom getInstance(String algorithm) throws
+    NoSuchAlgorithmException
+  {
+    Provider p[] = Security.getProviders();
+    for (int i = 0; i < p.length; i++)
+      {
+        try
+          {
+            return getInstance(algorithm, p[i]);
+          }
+        catch (NoSuchAlgorithmException ignored)
+          {
+          }
+      }
+
+    // None found.
+    throw new NoSuchAlgorithmException(algorithm);
+  }
+
+  /**
+   * Returns an instance of a SecureRandom. It creates the class
+   * for the specified algorithm from the named provider.
+   *
+   * @param algorithm The algorithm name.
+   * @param provider  The provider name.
+   * @return A new SecureRandom implementing the chosen algorithm.
+   * @throws NoSuchAlgorithmException If the named provider does not implement
+   *         the algorithm, or if the implementation cannot be
+   *         instantiated.
+   * @throws NoSuchProviderException If no provider named
+   *         <code>provider</code> is currently installed.
+   * @throws IllegalArgumentException If <code>provider</code> is null
+   *         or is empty.
+   */
+  public static SecureRandom getInstance(String algorithm, String provider)
+  throws NoSuchAlgorithmException, NoSuchProviderException
+  {
+    if (provider == null || provider.length() == 0)
+      throw new IllegalArgumentException("Illegal provider");
+
+    Provider p = Security.getProvider(provider);
+    if (p == null)
+      throw new NoSuchProviderException();
+    
+    return getInstance(algorithm, p);
+  }
+
+  /**
+   * Returns an instance of a SecureRandom. It creates the class for
+   * the specified algorithm from the given provider.
+   *
+   * @param algorithm The SecureRandom algorithm to create.
+   * @param provider  The provider to get the instance from.
+   * @throws NoSuchAlgorithmException If the algorithm cannot be found, or
+   *         if the class cannot be instantiated.
+   * @throws IllegalArgumentException If <code>provider</code> is null.
+   */
+  public static SecureRandom getInstance(String algorithm, Provider provider)
+  throws NoSuchAlgorithmException
+  {
+    if (provider == null)
+      throw new IllegalArgumentException("Illegal provider");
+    try
+      {
+        return new SecureRandom((SecureRandomSpi)
+          Engine.getInstance(SECURE_RANDOM, algorithm, provider),
+          provider);
+      }
+    catch (java.lang.reflect.InvocationTargetException ite)
+      {
+	throw new NoSuchAlgorithmException(algorithm);
+      }
+    catch (ClassCastException cce)
+      {
+        throw new NoSuchAlgorithmException(algorithm);
+      }
+  }
+
+  // Instance methods.
+  // ------------------------------------------------------------------------
+
+  /**
+     Returns the provider being used by the current SecureRandom class.
+
+     @return The provider from which this SecureRandom was attained
+   */
+  public final Provider getProvider()
+  {
+    return provider;
+  }
+
+  /**
+     Seeds the SecureRandom. The class is re-seeded for each call and 
+     each seed builds on the previous seed so as not to weaken security.
+
+     @param seed seed bytes to seed with
+   */
+  public void setSeed(byte[] seed)
+  {
+    secureRandomSpi.engineSetSeed(seed);
+  }
+
+  /**
+     Seeds the SecureRandom. The class is re-seeded for each call and 
+     each seed builds on the previous seed so as not to weaken security.
+
+     @param seed 8 seed bytes to seed with
+   */
+  public void setSeed(long seed)
+  {
+    // This particular setSeed will be called by Random.Random(), via
+    // our own constructor, before secureRandomSpi is initialized.  In
+    // this case we can't call a method on secureRandomSpi, and we
+    // definitely don't want to throw a NullPointerException.
+    // Therefore we test.
+    if (secureRandomSpi != null)
+      {
+        byte tmp[] = { (byte) (0xff & (seed >> 56)),
+		       (byte) (0xff & (seed >> 48)),
+		       (byte) (0xff & (seed >> 40)),
+		       (byte) (0xff & (seed >> 32)),
+		       (byte) (0xff & (seed >> 24)),
+		       (byte) (0xff & (seed >> 16)),
+		       (byte) (0xff & (seed >> 8)),
+		       (byte) (0xff & seed)
+        };
+        secureRandomSpi.engineSetSeed(tmp);
+      }
+  }
+
+  /**
+     Generates a user specified number of bytes. This function
+     is the basis for all the random functions.
+
+     @param bytes array to store generated bytes in
+   */
+  public void nextBytes(byte[] bytes)
+  {
+    randomBytesUsed += bytes.length;
+    counter++;
+    secureRandomSpi.engineNextBytes(bytes);
+  }
+
+  /**
+     Generates an integer containing the user specified
+     number of random bits. It is right justified and padded
+     with zeros.
+
+     @param numBits number of random bits to get, 0 <= numBits <= 32;
+
+     @return the random bits
+   */
+  protected final int next(int numBits)
+  {
+    if (numBits == 0)
+      return 0;
+
+    byte tmp[] = new byte[numBits / 8 + (1 * (numBits % 8))];
+
+    secureRandomSpi.engineNextBytes(tmp);
+    randomBytesUsed += tmp.length;
+    counter++;
+
+    int ret = 0;
+
+    for (int i = 0; i < tmp.length; i++)
+      ret |= (tmp[i] & 0xFF) << (8 * i);
+
+    long mask = (1L << numBits) - 1;
+    return (int) (ret & mask);
+  }
+
+  /**
+     Returns the given number of seed bytes. This method is
+     maintained only for backwards capability. 
+
+     @param numBytes number of seed bytes to get
+
+     @return an array containing the seed bytes
+   */
+  public static byte[] getSeed(int numBytes)
+  {
+    byte tmp[] = new byte[numBytes];
+
+    new Random().nextBytes(tmp);
+    return tmp;
+    //return secureRandomSpi.engineGenerateSeed( numBytes );
+  }
+
+  /**
+     Returns the specified number of seed bytes.
+
+     @param numBytes number of seed bytes to get
+
+     @return an array containing the seed bytes
+   */
+  public byte[] generateSeed(int numBytes)
+  {
+    return secureRandomSpi.engineGenerateSeed(numBytes);
+  }
 
 }




More information about the kaffe mailing list