diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c07140dd412..d9c65cc89b1 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,19 @@ +2002-12-13 Casey Marshall + Mark Wielaard + + * 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 + + * java/security/Security.java (loadProviders): Increment i only once. + 2002-12-12 Mark Wielaard * java/lang/ClassLoader.java (resolveClass0): Transform diff --git a/libjava/java/security/SecureRandom.java b/libjava/java/security/SecureRandom.java index 31701cb6fd9..a0b7f95f397 100644 --- a/libjava/java/security/SecureRandom.java +++ b/libjava/java/security/SecureRandom.java @@ -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 @@ public class SecureRandom extends Random //Serialized Field long counter = 0; //Serialized - MessageDigest digest = null; Provider provider = null; byte[] randomBytes = null; //Always null int randomBytesUsed = 0; @@ -83,41 +82,29 @@ public class SecureRandom extends Random 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 @@ public class SecureRandom extends Random 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++) + for (int 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) - { - throw new NoSuchAlgorithmException("Illegal Access"); + try + { + return getInstance(algorithm, p[i]); + } + catch (NoSuchAlgorithmException ignored) { } } + // None found. + throw new NoSuchAlgorithmException(algorithm); } /** @@ -222,33 +186,91 @@ public class SecureRandom extends Random 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); + /** + Returns an instance of a SecureRandom. It creates the class for + the specified algorithm from the given provider. - String classname = p.getProperty(key.toString()); - if (classname == null) - throw new NoSuchAlgorithmException(); + @param algorithm The SecureRandom algorithm to create. + @param provider The provider to get the instance from. - 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) - { - throw new NoSuchAlgorithmException("Illegal Access"); - } + @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(); ) + { + // 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); } /** diff --git a/libjava/java/security/Security.java b/libjava/java/security/Security.java index 8c84c3f7978..bf7a993ad47 100644 --- a/libjava/java/security/Security.java +++ b/libjava/java/security/Security.java @@ -89,7 +89,7 @@ public final class Security extends Object 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 @@ public final class Security extends Object try { providers.addElement(Class.forName(name).newInstance()); - i++; } catch (ClassNotFoundException x) { @@ -114,6 +113,7 @@ public final class Security extends Object if (exception != null) System.err.println ("Error loading security provider " + name + ": " + exception); + i++; } } catch (FileNotFoundException ignored)