This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
FYI: java.security provider framework fixes
- From: Mark Wielaard <mark at klomp dot org>
- To: java-patches at gcc dot gnu dot org
- Date: 13 Dec 2002 15:19:58 +0100
- Subject: FYI: java.security provider framework fixes
- Organization:
Hi,
The following fixes one of the last known issues with using the
java.security provider framework. These were found (and fixed) by the
GNU Crypto developers and have already been applied to GNU Classpath.
2002-12-13 Casey Marshall <rsdio@metastatic.org>
Mark Wielaard <mark@klomp.org>
* java/security/SecurityRandom (digest): Removed field.
(SecureRandom): Check all providers for case-insensitive SecureRandom
implementation. Don't ignore classname == null. Fallback to SHA1PRNG
if necessary.
(getInstance(String,Provider,boolean): New method.
(getInstance(String)): Use new method.
(getInstance(String,String)): Likewise.
(getInstance(String,Provider)): Likewise.
2002-12-13 Casey Marshall <rsdio@metastatic.org>
* java/security/Security.java (loadProviders): Increment i only once.
I have added tests to Mauve for SecureRandom and the GNU Crypto
testsuite now also succeeds its SecureRandom tests.
Cheers,
Mark
Index: java/security/SecureRandom.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/SecureRandom.java,v
retrieving revision 1.6
diff -u -r1.6 SecureRandom.java
--- java/security/SecureRandom.java 4 Oct 2002 20:15:07 -0000 1.6
+++ java/security/SecureRandom.java 13 Dec 2002 14:14:21 -0000
@@ -1,5 +1,5 @@
/* SecureRandom.java --- Secure Random class implmentation
- Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -53,7 +53,6 @@
//Serialized Field
long counter = 0; //Serialized
- MessageDigest digest = null;
Provider provider = null;
byte[] randomBytes = null; //Always null
int randomBytesUsed = 0;
@@ -83,41 +82,29 @@
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)
- break;
+ 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) { }
+ }
+ }
}
- if (classname != null)
- break;
}
- //if( classname == null)
- // throw new NoSuchAlgorithmException();
-
- try
- {
- this.secureRandomSpi =
- (SecureRandomSpi) Class.forName(classname).newInstance();
-
- //s.algorithm = algorithm;
- this.provider = p[i];
- }
- catch (ClassNotFoundException cnfe)
- {
- //throw new NoSuchAlgorithmException("Class not found");
- }
- catch (InstantiationException ie)
- {
- //throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
- {
- //throw new NoSuchAlgorithmException("Illegal Access");
- }
+ // Nothing found. Fall back to SHA1PRNG
+ secureRandomSpi = new gnu.java.security.provider.SHA1PRNG();
}
/**
@@ -167,40 +154,17 @@
NoSuchAlgorithmException
{
Provider p[] = Security.getProviders();
-
- //Format of Key: SecureRandom.algname
- StringBuffer key = new StringBuffer("SecureRandom.");
- key.append(algorithm);
-
- String classname = null;
- int i;
- for (i = 0; i < p.length; i++)
- {
- if ((classname = p[i].getProperty(key.toString())) != null)
- break;
- }
-
- if (classname == null)
- throw new NoSuchAlgorithmException();
-
- try
- {
- return new SecureRandom((SecureRandomSpi) Class.forName(classname).
- newInstance(), p[i]);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new NoSuchAlgorithmException("Class not found");
- }
- catch (InstantiationException ie)
- {
- throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
+ for (int i = 0; i < p.length; i++)
{
- throw new NoSuchAlgorithmException("Illegal Access");
+ try
+ {
+ return getInstance(algorithm, p[i]);
+ }
+ catch (NoSuchAlgorithmException ignored) { }
}
+ // None found.
+ throw new NoSuchAlgorithmException(algorithm);
}
/**
@@ -222,33 +186,91 @@
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException();
+
+ return getInstance(algorithm, p);
+ }
- //Format of Key: SecureRandom.algName
- StringBuffer key = new StringBuffer("SecureRandom.");
- key.append(algorithm);
-
- String classname = p.getProperty(key.toString());
- if (classname == null)
- throw new NoSuchAlgorithmException();
+ /**
+ Returns an instance of a SecureRandom. It creates the class for
+ the specified algorithm from the given provider.
- try
- {
- return new SecureRandom((SecureRandomSpi) Class.forName(classname).
- newInstance(), p);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new NoSuchAlgorithmException("Class not found");
- }
- catch (InstantiationException ie)
- {
- throw new NoSuchAlgorithmException("Class instantiation failed");
- }
- catch (IllegalAccessException iae)
+ @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.
+ */
+ public static SecureRandom getInstance(String algorithm,
+ Provider provider) throws
+ NoSuchAlgorithmException
+ {
+ return getInstance(algorithm, provider, true);
+ }
+
+ /**
+ Creates the instance of SecureRandom, recursing to resolve aliases.
+
+ @param algorithm The SecureRandom algorithm to create.
+ @param provider The provider to get the implementation from.
+ @param recurse Whether or not to recurse to resolve aliases.
+
+ @throws NoSuchAlgorithmException If the algorithm cannot be found,
+ if there are too many aliases, or if the class cannot be
+ instantiated.
+ */
+ private static SecureRandom getInstance(String algorithm,
+ Provider provider,
+ boolean recurse)
+ throws NoSuchAlgorithmException
+ {
+ String msg = algorithm;
+ for (Enumeration e = provider.propertyNames(); e.hasMoreElements(); )
{
- throw new NoSuchAlgorithmException("Illegal Access");
+ // We could replace the boolean with an integer, incrementing it
+ // every
+ String key = (String) e.nextElement();
+ if (key.startsWith("SECURERANDOM.")
+ && key.substring(13).equalsIgnoreCase(algorithm))
+ {
+ try
+ {
+ Class c = Class.forName(provider.getProperty(key));
+ return new SecureRandom((SecureRandomSpi) c.newInstance(),
+ provider);
+ }
+ catch (Throwable ignored) { }
+ }
+ else if (key.startsWith("ALG.ALIAS.SECURERANDOM.")
+ && key.substring(23).equalsIgnoreCase(algorithm) && recurse)
+ {
+ try
+ {
+ // First see if this alias refers to a class in this
+ // provider.
+ return getInstance(provider.getProperty(key), provider, false);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ Provider[] provs = Security.getProviders();
+ for (int i = 0; i < provs.length; i++)
+ {
+ if (provs[i] == provider)
+ continue;
+ // Now try other providers for the implementation
+ try
+ {
+ return getInstance(provider.getProperty(key),
+ provs[i], false);
+ }
+ catch (NoSuchAlgorithmException nsae2)
+ {
+ msg = nsae2.getMessage();
+ }
+ }
+ }
+ }
}
-
+ throw new NoSuchAlgorithmException(algorithm);
}
/**
Index: java/security/Security.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/Security.java,v
retrieving revision 1.9
diff -u -r1.9 Security.java
--- java/security/Security.java 17 Nov 2002 00:10:24 -0000 1.9
+++ java/security/Security.java 13 Dec 2002 14:14:21 -0000
@@ -89,7 +89,7 @@
int i = 1;
String name;
- while ((name = secprops.getProperty("security.provider." + i++)) !=
+ while ((name = secprops.getProperty("security.provider." + i)) !=
null)
{
Exception exception = null;
@@ -97,7 +97,6 @@
try
{
providers.addElement(Class.forName(name).newInstance());
- i++;
}
catch (ClassNotFoundException x)
{
@@ -114,6 +113,7 @@
if (exception != null)
System.err.println ("Error loading security provider " + name
+ ": " + exception);
+ i++;
}
}
catch (FileNotFoundException ignored)