/* Security.java --- Java base security class implementation
   Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006
   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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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.classpath.SystemProperties;

import gnu.classpath.Configuration;
// GCJ LOCAL - We don't have VMStackWalker yet.
// import gnu.classpath.VMStackWalker;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

/**
 * This class centralizes all security properties and common security methods.
 * One of its primary uses is to manage security providers.
 *
 * @author Mark Benvenuto (ivymccough@worldnet.att.net)
 */
public final class Security
{
  private static final String ALG_ALIAS = "Alg.Alias.";

  private static Vector providers = new Vector();
  private static Properties secprops = new Properties();
  
  static
    {
      String base = SystemProperties.getProperty("gnu.classpath.home.url");
      String vendor = SystemProperties.getProperty("gnu.classpath.vm.shortname");

      // Try VM specific security file
      boolean loaded = loadProviders (base, vendor);
    
      // Append classpath standard provider if possible
      if (!loadProviders (base, "classpath")
	  && !loaded
	  && providers.size() == 0)
	  {
	      if (Configuration.DEBUG)
		  {
		      /* No providers found and both security files failed to
		       * load properly. Give a warning in case of DEBUG is
		       * enabled. Could be done with java.util.logging later.
		       */
		      System.err.println
			  ("WARNING: could not properly read security provider files:");
		      System.err.println
			  ("         " + base + "/security/" + vendor
			   + ".security");
		      System.err.println
			  ("         " + base + "/security/" + "classpath"
			   + ".security");
		      System.err.println
			  ("         Falling back to standard GNU security provider");
		  }
              // Note that this matches our classpath.security file.
	      providers.addElement (new gnu.java.security.provider.Gnu());
	      providers.addElement(new gnu.javax.crypto.jce.GnuCrypto());
              providers.addElement(new gnu.javax.crypto.jce.GnuSasl());
              providers.addElement(new gnu.javax.net.ssl.provider.Jessie());
              providers.addElement(new gnu.javax.security.auth.callback.GnuCallbacks());
	  }
    }
  // This class can't be instantiated.
  private Security()
  {
  }

  /**
   * Tries to load the vender specific security providers from the given base
   * URL. Returns true if the resource could be read and completely parsed
   * successfully, false otherwise.
   */
  private static boolean loadProviders(String baseUrl, String vendor)
  {
    if (baseUrl == null || vendor == null)
      return false;

    boolean result = true;
    String secfilestr = baseUrl + "/security/" + vendor + ".security";
    try
      {
	InputStream fin = new URL(secfilestr).openStream();
	secprops.load(fin);

	int i = 1;
	String name;
	while ((name = secprops.getProperty("security.provider." + i)) != null)
	  {
	    Exception exception = null;
	    try
	      {
            ClassLoader sys = ClassLoader.getSystemClassLoader();
		providers.addElement(Class.forName(name, true, sys).newInstance());
	      }
	    catch (ClassNotFoundException x)
	      {
	        exception = x;
	      }
	    catch (InstantiationException x)
	      {
	        exception = x;
	      }
	    catch (IllegalAccessException x)
	      {
	        exception = x;
	      }

	    if (exception != null)
	      {
		System.err.println ("WARNING: Error loading security provider "
				    + name + ": " + exception);
		result = false;
	      }
	    i++;
	  }
      }
    catch (IOException ignored)
      {
	result = false;
      }

    return result;
  }

  /**
   * Returns the value associated to a designated property name for a given
   * algorithm.
   * 
   * @param algName
   *          the algorithm name.
   * @param propName
   *          the name of the property to return.
   * @return the value of the specified property or <code>null</code> if none
   *         found.
   * @deprecated Use the provider-based and algorithm-independent
   *             {@link AlgorithmParameters} and {@link KeyFactory} engine
   *             classes instead.
   */
  public static String getAlgorithmProperty(String algName, String propName)
  {
    if (algName == null || propName == null)
      return null;

    String property = String.valueOf(propName) + "." + String.valueOf(algName);
    Provider p;
    for (Iterator i = providers.iterator(); i.hasNext(); )
      {
        p = (Provider) i.next();
        for (Iterator j = p.keySet().iterator(); j.hasNext(); )
          {
            String key = (String) j.next();
            if (key.equalsIgnoreCase(property))
              return p.getProperty(key);
          }
      }
    return null;
  }

  /**
   * Inserts a new designated {@link Provider} at a designated (1-based)
   * position in the current list of installed {@link Provider}s,
   * 
   * @param provider
   *          the new {@link Provider} to add.
   * @param position
   *          the position (starting from 1) of where to install
   *          <code>provider</code>.
   * @return the actual position, in the list of installed Providers. Returns
   *         <code>-1</code> if <code>provider</code> was laready in the
   *         list. The actual position may be different than the desired
   *         <code>position</code>.
   * @throws SecurityException
   *           if a {@link SecurityManager} is installed and it disallows this
   *           operation.
   * @see #getProvider(String)
   * @see #removeProvider(String)
   * @see SecurityPermission
   */
  public static int insertProviderAt(Provider provider, int position)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSecurityAccess("insertProvider." + provider.getName());

    position--;
    int max = providers.size ();
    for (int i = 0; i < max; i++)
      {
	if (((Provider) providers.elementAt(i)).getName().equals(provider.getName()))
	  return -1;
      }

    if (position < 0)
      position = 0;
    if (position > max)
      position = max;

    providers.insertElementAt(provider, position);

    return position + 1;
  }

  /**
   * Appends the designated new {@link Provider} to the current list of
   * installed {@link Provider}s.
   * 
   * @param provider
   *          the new {@link Provider} to append.
   * @return the position (starting from 1) of <code>provider</code> in the
   *         current list of {@link Provider}s, or <code>-1</code> if
   *         <code>provider</code> was already there.
   * @throws SecurityException
   *           if a {@link SecurityManager} is installed and it disallows this
   *           operation.
   * @see #getProvider(String)
   * @see #removeProvider(String)
   * @see SecurityPermission
   */
  public static int addProvider(Provider provider)
  {
    return insertProviderAt (provider, providers.size () + 1);
  }

  /**
   * Removes an already installed {@link Provider}, given its name, from the
   * current list of installed {@link Provider}s.
   * 
   * @param name
   *          the name of an already installed {@link Provider} to remove.
   * @throws SecurityException
   *           if a {@link SecurityManager} is installed and it disallows this
   *           operation.
   * @see #getProvider(String)
   * @see #addProvider(Provider)
   */
  public static void removeProvider(String name)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSecurityAccess("removeProvider." + name);

    int max = providers.size ();
    for (int i = 0; i < max; i++)
      {
	if (((Provider) providers.elementAt(i)).getName().equals(name))
	  {
	    providers.remove(i);
	    break;
	  }
      }
  }

  /**
   * Returns the current list of installed {@link Provider}s as an array
   * ordered according to their installation preference order.
   * 
   * @return an array of all the installed providers.
   */
  public static Provider[] getProviders()
  {
    Provider[] array = new Provider[providers.size ()];
    providers.copyInto (array);
    return array;
  }

  /**
   * Returns an already installed {@link Provider} given its name.
   * 
   * @param name
   *          the name of an already installed {@link Provider}.
   * @return the {@link Provider} known by <code>name</code>. Returns
   *         <code>null</code> if the current list of {@link Provider}s does
   *         not include one named <code>name</code>.
   * @see #removeProvider(String)
   * @see #addProvider(Provider)
   */
  public static Provider getProvider(String name)
  {
    if (name == null)
      return null;
    else
      {
        name = name.trim();
        if (name.length() == 0)
          return null;
      }
    Provider p;
    int max = providers.size ();
    for (int i = 0; i < max; i++)
      {
	p = (Provider) providers.elementAt(i);
	if (p.getName().equals(name))
	  return p;
      }
    return null;
  }

  /**
   * Returns the value associated with a Security propery.
   * 
   * @param key
   *          the key of the property to fetch.
   * @return the value of the Security property associated with
   *         <code>key</code>. Returns <code>null</code> if no such property
   *         was found.
   * @throws SecurityException
   *           if a {@link SecurityManager} is installed and it disallows this
   *           operation.
   * @see #setProperty(String, String)
   * @see SecurityPermission
   */
  public static String getProperty(String key)
  {
    // GCJ LOCAL - We don't have VMStackWalker yet.
    // XXX To prevent infinite recursion when the SecurityManager calls us,
    // don't do a security check if the caller is trusted (by virtue of having
    // been loaded by the bootstrap class loader).
    SecurityManager sm = System.getSecurityManager();
    // if (sm != null && VMStackWalker.getCallingClassLoader() != null)
    if (sm != null)
      sm.checkSecurityAccess("getProperty." + key);

    return secprops.getProperty(key);
  }

  /**
   * Sets or changes a designated Security property to a designated value.
   * 
   * @param key
   *          the name of the property to set.
   * @param datum
   *          the new value of the property.
   * @throws SecurityException
   *           if a {@link SecurityManager} is installed and it disallows this
   *           operation.
   * @see #getProperty(String)
   * @see SecurityPermission
   */
  public static void setProperty(String key, String datum)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSecurityAccess("setProperty." + key);

    if (datum == null)
      secprops.remove(key);
    else
      secprops.put(key, datum);
  }

  /**
   * For a given <i>service</i> (e.g. Signature, MessageDigest, etc...) this
   * method returns the {@link Set} of all available algorithm names (instances
   * of {@link String}, from all currently installed {@link Provider}s.
   * 
   * @param serviceName
   *          the case-insensitive name of a service (e.g. Signature,
   *          MessageDigest, etc).
   * @return a {@link Set} of {@link String}s containing the names of all
   *         algorithm names provided by all of the currently installed
   *         {@link Provider}s.
   * @since 1.4
   */
  public static Set getAlgorithms(String serviceName)
  {
    HashSet result = new HashSet();
    if (serviceName == null || serviceName.length() == 0)
      return result;

    serviceName = serviceName.trim();
    if (serviceName.length() == 0)
      return result;

    serviceName = serviceName.toUpperCase()+".";
    Provider[] providers = getProviders();
    int ndx;
    for (int i = 0; i < providers.length; i++)
      for (Enumeration e = providers[i].propertyNames(); e.hasMoreElements(); )
        {
          String service = ((String) e.nextElement()).trim();
          if (service.toUpperCase().startsWith(serviceName))
            {
              service = service.substring(serviceName.length()).trim();
              ndx = service.indexOf(' '); // get rid of attributes
              if (ndx != -1)
                service = service.substring(0, ndx);
              result.add(service);
            }
        }
    return Collections.unmodifiableSet(result);
  }

  /**
   * Returns an array of currently installed {@link Provider}s, ordered
   * according to their installation preference order, which satisfy a given
   * <i>selection</i> criterion.
   * 
   * <p>This implementation recognizes a <i>selection</i> criterion written in
   * one of two following forms:</p>
   * 
   * <ul>
   *   <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: Where
   *   <i>crypto_service</i> is a case-insensitive string, similar to what has
   *   been described in the {@link #getAlgorithms(String)} method, and
   *   <i>algorithm_or_type</i> is a known case-insensitive name of an
   *   Algorithm, or one of its aliases.
   *   
   *   <p>For example, "CertificateFactory.X.509" would return all the installed
   *   {@link Provider}s which provide a <i>CertificateFactory</i>
   *   implementation of <i>X.509</i>.</p></li>
   *   
   *   <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:&lt;value&gt;:
   *   Where <i>crypto_service</i> is a case-insensitive string, similar to what
   *   has been described in the {@link #getAlgorithms(String)} method,
   *   <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
   *   or one of its aliases, <i>attribute_name</i> is a case-insensitive
   *   property name with no whitespace characters, and no dots, in-between, and
   *   <i>value</i> is a {@link String} with no whitespace characters in-between.
   *   
   *   <p>For example, "Signature.Sha1WithDSS KeySize:1024" would return all the
   *   installed {@link Provider}s which declared their ability to provide
   *   <i>Signature</i> services, using the <i>Sha1WithDSS</i> algorithm with
   *   key sizes of <i>1024</i>.</p></li>
   * </ul>
   * 
   * @param filter
   *          the <i>selection</i> criterion for selecting among the installed
   *          {@link Provider}s.
   * @return all the installed {@link Provider}s which satisfy the <i>selection</i>
   *         criterion. Returns <code>null</code> if no installed
   *         {@link Provider}s were found which satisfy the <i>selection</i>
   *         criterion. Returns ALL installed {@link Provider}s if
   *         <code>filter</code> is <code>null</code> or is an empty string.
   * @throws InvalidParameterException
   *           if an exception occurs while parsing the <code>filter</code>.
   * @see #getProviders(Map)
   */
  public static Provider[] getProviders(String filter)
  {
    if (providers == null || providers.isEmpty())
      return null;

    if (filter == null || filter.length() == 0)
      return getProviders();

    HashMap map = new HashMap(1);
    int i = filter.indexOf(':');
    if (i == -1) // <service>.<algorithm>
      map.put(filter, "");
    else // <service>.<algorithm> <attribute>:<value>
      map.put(filter.substring(0, i), filter.substring(i+1));

    return getProviders(map);
  }

  /**
   * Returns an array of currently installed {@link Provider}s which satisfy a
   * set of <i>selection</i> criteria.
   * 
   * <p>The <i>selection</i> criteria are defined in a {@link Map} where each
   * element specifies a <i>selection</i> querry. The <i>Keys</i> in this
   * {@link Map} must be in one of the two following forms:</p>
   * 
   * <ul>
   *   <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: Where
   *   <i>crypto_service</i> is a case-insensitive string, similar to what has
   *   been described in the {@link #getAlgorithms(String)} method, and
   *   <i>algorithm_or_type</i> is a case-insensitive known name of an
   *   Algorithm, or one of its aliases. The <i>value</i> of the entry in the
   *   {@link Map} for such a <i>Key</i> MUST be the empty string.
   *   {@link Provider}s which provide an implementation for the designated
   *   <i>service algorithm</i> are included in the result.</li>
   *   
   *   <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:
   *   Where <i>crypto_service</i> is a case-insensitive string, similar to what
   *   has been described in the {@link #getAlgorithms(String)} method,
   *   <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
   *   or one of its aliases, and <i>attribute_name</i> is a case-insensitive
   *   property name with no whitespace characters, and no dots, in-between. The
   *   <i>value</i> of the entry in this {@link Map} for such a <i>Key</i> MUST
   *   NOT be <code>null</code> or an empty string. {@link Provider}s which
   *   declare the designated <i>attribute_name</i> and <i>value</i> for the
   *   designated <i>service algorithm</i> are included in the result.</li>
   * </ul>
   * 
   * @param filter
   *          a {@link Map} of <i>selection querries</i>.
   * @return all currently installed {@link Provider}s which satisfy ALL the
   *         <i>selection</i> criteria defined in <code>filter</code>.
   *         Returns ALL installed {@link Provider}s if <code>filter</code>
   *         is <code>null</code> or empty.
   * @throws InvalidParameterException
   *           if an exception is encountered while parsing the syntax of the
   *           {@link Map}'s <i>keys</i>.
   * @see #getProviders(String)
   */
  public static Provider[] getProviders(Map filter)
  {
    if (providers == null || providers.isEmpty())
      return null;

    if (filter == null)
      return getProviders();

    Set querries = filter.keySet();
    if (querries == null || querries.isEmpty())
      return getProviders();

    LinkedHashSet result = new LinkedHashSet(providers); // assume all
    int dot, ws;
    String querry, service, algorithm, attribute, value;
    LinkedHashSet serviceProviders = new LinkedHashSet(); // preserve insertion order
    for (Iterator i = querries.iterator(); i.hasNext(); )
      {
        querry = (String) i.next();
        if (querry == null) // all providers
          continue;

        querry = querry.trim();
        if (querry.length() == 0) // all providers
          continue;

        dot = querry.indexOf('.');
        if (dot == -1) // syntax error
          throw new InvalidParameterException(
              "missing dot in '" + String.valueOf(querry)+"'");

        value = (String) filter.get(querry);
        // deconstruct querry into [service, algorithm, attribute]
        if (value == null || value.trim().length() == 0) // <service>.<algorithm>
          {
            value = null;
            attribute = null;
            service = querry.substring(0, dot).trim();
            algorithm = querry.substring(dot+1).trim();
          }
        else // <service>.<algorithm> <attribute>
          {
            ws = querry.indexOf(' ');
            if (ws == -1)
              throw new InvalidParameterException(
                  "value (" + String.valueOf(value) +
                  ") is not empty, but querry (" + String.valueOf(querry) +
                  ") is missing at least one space character");
            value = value.trim();
            attribute = querry.substring(ws+1).trim();
            // was the dot in the attribute?
            if (attribute.indexOf('.') != -1)
              throw new InvalidParameterException(
                  "attribute_name (" + String.valueOf(attribute) +
                  ") in querry (" + String.valueOf(querry) + ") contains a dot");

            querry = querry.substring(0, ws).trim();
            service = querry.substring(0, dot).trim();
            algorithm = querry.substring(dot+1).trim();
          }

        // service and algorithm must not be empty
        if (service.length() == 0)
          throw new InvalidParameterException(
              "<crypto_service> in querry (" + String.valueOf(querry) +
              ") is empty");

        if (algorithm.length() == 0)
          throw new InvalidParameterException(
              "<algorithm_or_type> in querry (" + String.valueOf(querry) +
              ") is empty");

        selectProviders(service, algorithm, attribute, value, result, serviceProviders);
        result.retainAll(serviceProviders); // eval next retaining found providers
        if (result.isEmpty()) // no point continuing
          break;
      }

    if (result.isEmpty())
      return null;

    return (Provider[]) result.toArray(new Provider[result.size()]);
  }

  private static void selectProviders(String svc, String algo, String attr,
                                      String val, LinkedHashSet providerSet,
                                      LinkedHashSet result)
  {
    result.clear(); // ensure we start with an empty result set
    for (Iterator i = providerSet.iterator(); i.hasNext(); )
      {
        Provider p = (Provider) i.next();
        if (provides(p, svc, algo, attr, val))
          result.add(p);
      }
  }

  private static boolean provides(Provider p, String svc, String algo,
                                  String attr, String val)
  {
    Iterator it;
    String serviceDotAlgorithm = null;
    String key = null;
    String realVal;
    boolean found = false;
    // if <svc>.<algo> <attr> is in the set then so is <svc>.<algo>
    // but it may be stored under an alias <algo>. resolve
    outer: for (int r = 0; r < 3; r++) // guard against circularity
      {
        serviceDotAlgorithm = (svc+"."+String.valueOf(algo)).trim();
        for (it = p.keySet().iterator(); it.hasNext(); )
          {
            key = (String) it.next();
            if (key.equalsIgnoreCase(serviceDotAlgorithm)) // eureka
              {
                found = true;
                break outer;
              }
            // it may be there but as an alias
            if (key.equalsIgnoreCase(ALG_ALIAS + serviceDotAlgorithm))
              {
                algo = p.getProperty(key);
                continue outer;
              }
            // else continue inner
          }
      }

    if (!found)
      return false;

    // found a candidate for the querry.  do we have an attr to match?
    if (val == null) // <service>.<algorithm> querry
      return true;

    // <service>.<algorithm> <attribute>; find the key entry that match
    String realAttr;
    int limit = serviceDotAlgorithm.length() + 1;
    for (it = p.keySet().iterator(); it.hasNext(); )
      {
        key = (String) it.next();
        if (key.length() <= limit)
          continue;

        if (key.substring(0, limit).equalsIgnoreCase(serviceDotAlgorithm+" "))
          {
            realAttr = key.substring(limit).trim();
            if (! realAttr.equalsIgnoreCase(attr))
              continue;

            // eveything matches so far.  do the value
            realVal = p.getProperty(key);
            if (realVal == null)
              return false;

            realVal = realVal.trim();
            // is it a string value?
            if (val.equalsIgnoreCase(realVal))
              return true;

            // assume value is a number. cehck for greater-than-or-equal
            return (new Integer(val).intValue() >= new Integer(realVal).intValue());
          }
      }

    return false;
  }
}
