diff options
Diffstat (limited to 'gnu/java/security/Engine.java')
-rw-r--r-- | gnu/java/security/Engine.java | 212 |
1 files changed, 119 insertions, 93 deletions
diff --git a/gnu/java/security/Engine.java b/gnu/java/security/Engine.java index f3be45075..44318af8e 100644 --- a/gnu/java/security/Engine.java +++ b/gnu/java/security/Engine.java @@ -42,6 +42,7 @@ import java.lang.reflect.InvocationTargetException; import java.security.NoSuchAlgorithmException; import java.security.Provider; +import java.util.Enumeration; /** * Generic implementation of the getInstance methods in the various @@ -78,145 +79,170 @@ public final class Engine /** This class cannot be instantiated. */ private Engine() { } - // Class method. - // ------------------------------------------------------------------------ - /** - * Get the implementation for <i>algorithm</i> for service - * <i>service</i> from <i>provider</i>. The service is e.g. - * "Signature", and the algorithm "DSA". - * - * @param service The service name. + * Return the implementation for <i>algorithm</i> for service <i>service</i> + * from <i>provider</i>. The service is e.g. "Signature", and the algorithm + * "DSA". + * + * @param service The service name. * @param algorithm The name of the algorithm to get. - * @param provider The provider to get the implementation from. - * @return The engine class for the specified algorithm; the object - * returned is typically a subclass of the SPI class for that - * service, but callers should check that this is so. - * @throws NoSuchAlgorithmException If the implementation cannot be - * found or cannot be instantiated. - * @throws InvocationTargetException If the SPI class's constructor - * throws an exception. - * @throws IllegalArgumentException If any of the three arguments are null. + * @param provider The provider to get the implementation from. + * @return The engine class for the specified algorithm; the object returned + * is typically a subclass of the SPI class for that service, but + * callers should check that this is so. + * @throws NoSuchAlgorithmException If the implementation cannot be found or + * cannot be instantiated. + * @throws InvocationTargetException If the SPI class's constructor throws an + * exception. + * @throws IllegalArgumentException If any of the three arguments is null. */ public static Object getInstance(String service, String algorithm, Provider provider) - throws InvocationTargetException, NoSuchAlgorithmException + throws InvocationTargetException, NoSuchAlgorithmException { return getInstance(service, algorithm, provider, NO_ARGS); } /** - * Get the implementation for <i>algorithm</i> for service - * <i>service</i> from <i>provider</i>, passing <i>initArgs</i> to the - * SPI class's constructor (which cannot be null; pass a zero-length - * array if the SPI takes no arguments). The service is e.g. - * "Signature", and the algorithm "DSA". - * - * @param service The service name. + * Return the implementation for <i>algorithm</i> for service <i>service</i> + * from <i>provider</i>, passing <i>initArgs</i> to the SPI class's + * constructor (which cannot be null; pass a zero-length array if the SPI + * takes no arguments). The service is e.g. "Signature", and the algorithm + * "DSA". + * + * @param service The service name. * @param algorithm The name of the algorithm to get. - * @param provider The provider to get the implementation from. - * @param initArgs The arguments to pass to the SPI class's - * constructor (cannot be null). - * @return The engine class for the specified algorithm; the object - * returned is typically a subclass of the SPI class for that - * service, but callers should check that this is so. - * @throws NoSuchAlgorithmException If the implementation cannot be - * found or cannot be instantiated. - * @throws InvocationTargetException If the SPI class's constructor - * throws an exception. - * @throws IllegalArgumentException If any of the four arguments are null. + * @param provider The provider to get the implementation from. + * @param initArgs The arguments to pass to the SPI class's constructor + * (cannot be null). + * @return The engine class for the specified algorithm; the object returned + * is typically a subclass of the SPI class for that service, but + * callers should check that this is so. + * @throws NoSuchAlgorithmException If the implementation cannot be found or + * cannot be instantiated. + * @throws InvocationTargetException If the SPI class's constructor throws an + * exception. + * @throws IllegalArgumentException If any of the four arguments is + * <code>null</code> or if either <code>service</code>, or + * <code>algorithm</code> is an empty string. */ public static Object getInstance(String service, String algorithm, Provider provider, Object[] initArgs) - throws InvocationTargetException, NoSuchAlgorithmException + throws InvocationTargetException, NoSuchAlgorithmException { - if (service != null) - service = service.trim(); + if (service == null) + throw new IllegalArgumentException("service MUST NOT be null"); + service = service.trim(); + if (service.length() == 0) + throw new IllegalArgumentException("service MUST NOT be empty"); + if (algorithm == null) + throw new IllegalArgumentException("algorithm MUST NOT be null"); + algorithm = algorithm.trim(); + if (algorithm.length() == 0) + throw new IllegalArgumentException("algorithm MUST NOT be empty"); + if (provider == null) + throw new IllegalArgumentException("provider MUST NOT be null"); + if (initArgs == null) + throw new IllegalArgumentException("Constructor's parameters MUST NOT be null"); - if (algorithm != null) - algorithm = algorithm.trim(); - - if (service == null || service.length() == 0 - || algorithm == null || algorithm.length() == 0 - || provider == null || initArgs == null) - throw new IllegalArgumentException(); - - // If there is no property "service.algorithm" - if (provider.getProperty(service + "." + algorithm) == null) + Enumeration enumer = provider.propertyNames(); + String key; + String alias; + int count = 0; + boolean algorithmFound = false; + StringBuilder sb = new StringBuilder(); + while (enumer.hasMoreElements()) { - // Iterate through aliases, until we find the class name or resolve - // too many aliases. - String alias = null; - int count = 0; - while ((alias = provider.getProperty( - ALG_ALIAS + service + "." + algorithm)) != null) + key = (String) enumer.nextElement(); + if (key.equalsIgnoreCase(service + "." + algorithm)) + { + // remove the service portion from the key + algorithm = key.substring(service.length() + 1); + algorithmFound = true; + break; + } + else if (key.equalsIgnoreCase(ALG_ALIAS + service + "." + algorithm)) { - if (algorithm.equals(alias)) // Refers to itself! - break; - algorithm = alias; - if (count++ > MAX_ALIASES) - throw new NoSuchAlgorithmException("too many aliases"); + alias = (String) provider.getProperty(key); + if (! algorithm.equalsIgnoreCase(alias)) // does not refer to itself + { + algorithm = alias; + if (count++ > MAX_ALIASES) + { + sb.append("Algorithm [").append(algorithm) + .append("] of type [").append(service) + .append("] from provider [").append(provider) + .append("] has too many aliases"); + throw new NoSuchAlgorithmException(sb.toString()); + } + // need to reset enumeration to now look for the alias + enumer = provider.propertyNames(); + } } - if (provider.getProperty(service + "." + algorithm) == null) - throw new NoSuchAlgorithmException(algorithm); } - // Find and instantiate the implementation. + if (! algorithmFound) + { + sb.append("Algorithm [").append(algorithm).append("] of type [") + .append(service).append("] from provider [") + .append(provider).append("] is not found"); + throw new NoSuchAlgorithmException(sb.toString()); + } + + // Find and instantiate the implementation Class clazz = null; ClassLoader loader = provider.getClass().getClassLoader(); Constructor constructor = null; - String error = algorithm; - Throwable cause; - + String className = provider.getProperty(service + "." + algorithm); + sb.append("Class [").append(className).append("] for algorithm [") + .append(algorithm).append("] of type [").append(service) + .append("] from provider [").append(provider).append("] "); + Throwable cause = null; try { if (loader != null) - clazz = loader.loadClass(provider.getProperty(service+"."+algorithm)); + clazz = loader.loadClass(className); else - clazz = Class.forName(provider.getProperty(service+"."+algorithm)); + clazz = Class.forName(className); constructor = getCompatibleConstructor(clazz, initArgs); return constructor.newInstance(initArgs); } - catch (ClassNotFoundException cnfe) + catch (ClassNotFoundException x) { - error = "class not found: " + algorithm; - cause = cnfe; + sb.append("cannot not be found"); + cause = x; } - catch (IllegalAccessException iae) + catch (IllegalAccessException x) { - error = "illegal access: " + iae.getMessage(); - cause = iae; + sb.append("cannot be accessed"); + cause = x; } - catch (InstantiationException ie) + catch (InstantiationException x) { - error = "instantiation exception: " + ie.getMessage(); - cause = ie; + sb.append("cannot be instantiated"); + cause = x; } - catch (ExceptionInInitializerError eiie) + catch (ExceptionInInitializerError x) { - error = "exception in initializer: " + eiie.getMessage(); - cause = eiie; + sb.append("cannot be initialized"); + cause = x; } - catch (SecurityException se) + catch (SecurityException x) { - error = "security exception: " + se.getMessage(); - cause = se; + sb.append("caused a security violation"); + cause = x; } - catch (NoSuchMethodException nsme) + catch (NoSuchMethodException x) { - error = "no appropriate constructor found"; - cause = nsme; + sb.append("does not have/expose an appropriate constructor"); + cause = x; } - NoSuchAlgorithmException nsae = new NoSuchAlgorithmException(error); - nsae.initCause(cause); - - throw nsae; + NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString()); + x.initCause(cause); + throw x; } - // Own methods. - // ------------------------------------------------------------------------ - /** * Find a constructor in the given class that can take the specified * argument list, allowing any of which to be null. |