/* Properties.java -- run-time configuration properties.
   Copyright (C) 2003, 2004, 2006, 2010  Free Software Foundation, Inc.

This file is a 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 of the License, 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, 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 gnu.java.security;

import gnu.java.security.Configuration;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.PropertyPermission;
import java.util.logging.Logger;

/**
 * A global object containing build-specific properties that affect the
 * behaviour of the generated binaries from this library.
 */
public final class Properties
{
  private static final Logger log = Configuration.DEBUG ?
                        Logger.getLogger(Properties.class.getName()) : null;

  public static final String VERSION = "gnu.crypto.version";

  public static final String PROPERTIES_FILE = "gnu.crypto.properties.file";

  public static final String REPRODUCIBLE_PRNG = "gnu.crypto.with.reproducible.prng";

  public static final String CHECK_WEAK_KEYS = "gnu.crypto.with.check.for.weak.keys";

  public static final String DO_RSA_BLINDING = "gnu.crypto.with.rsa.blinding";

  private static final String TRUE = Boolean.TRUE.toString();

  private static final String FALSE = Boolean.FALSE.toString();

  private static final HashMap props = new HashMap();

  private static Properties singleton = null;

  private boolean reproducible = false;

  private boolean checkForWeakKeys = true;

  private boolean doRSABlinding = true;

  /** Trivial constructor to enforce Singleton pattern. */
  private Properties()
  {
    super();
    init();
  }

  /**
   * Returns the string representation of the library global configuration
   * property with the designated <code>key</code>.
   *
   * @param key the case-insensitive, non-null and non-empty name of a
   *          configuration property.
   * @return the string representation of the designated property, or
   *         <code>null</code> if such property is not yet set, or
   *         <code>key</code> is empty.
   */
  public static final synchronized String getProperty(String key)
  {
    if (key == null)
      return null;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(key, "read"));
    key = key.trim().toLowerCase();
    if ("".equals(key))
      return null;
    return (String) props.get(key);
  }

  /**
   * Sets the value of a designated library global configuration property, to a
   * string representation of what should be a legal value.
   *
   * @param key the case-insensitive, non-null and non-empty name of a
   *          configuration property.
   * @param value the non-null, non-empty string representation of a legal value
   *          of the configuration property named by <code>key</code>.
   */
  public static final synchronized void setProperty(String key, String value)
  {
    if (key == null || value == null)
      return;
    key = key.trim().toLowerCase();
    if ("".equals(key))
      return;
    if (key.equals(VERSION))
      return;
    value = value.trim();
    if ("".equals(value))
      return;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(key, "write"));
    if (key.equals(REPRODUCIBLE_PRNG)
        && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
      setReproducible(Boolean.valueOf(value).booleanValue());
    else if (key.equals(CHECK_WEAK_KEYS)
             && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
      setCheckForWeakKeys(Boolean.valueOf(value).booleanValue());
    else if (key.equals(DO_RSA_BLINDING)
             && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
      setDoRSABlinding(Boolean.valueOf(value).booleanValue());
    else
      props.put(key, value);
  }

  /**
   * A convenience method that returns, as a boolean, the library global
   * configuration property indicating if the default Pseudo Random Number
   * Generator produces, or not, the same bit stream when instantiated.
   *
   * @return <code>true</code> if the default PRNG produces the same bit
   *         stream with every VM instance. Returns <code>false</code> if the
   *         default PRNG is seeded with the time of day of its first
   *         invocation.
   */
  public static final synchronized boolean isReproducible()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "read"));
    return instance().reproducible;
  }

  /**
   * A convenience method that returns, as a boolean, the library global
   * configuration property indicating if the implementations of symmetric key
   * block ciphers check, or not, for possible/potential weak and semi-weak keys
   * that may be produced in the course of generating round encryption and/or
   * decryption keys.
   *
   * @return <code>true</code> if the cipher implementations check for weak
   *         and semi-weak keys. Returns <code>false</code> if the cipher
   *         implementations do not check for weak or semi-weak keys.
   */
  public static final synchronized boolean checkForWeakKeys()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "read"));
    return instance().checkForWeakKeys;
  }

  /**
   * A convenience method that returns, as a boolean, the library global
   * configuration property indicating if RSA decryption (RSADP primitive),
   * does, or not, blinding against timing attacks.
   *
   * @return <code>true</code> if the RSA decryption primitive includes a
   *         blinding operation. Returns <code>false</code> if the RSA
   *         decryption primitive does not include the additional blinding
   *         operation.
   */
  public static final synchronized boolean doRSABlinding()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "read"));
    return instance().doRSABlinding;
  }

  /**
   * A convenience method to set the global property for reproducibility of the
   * default PRNG bit stream output.
   *
   * @param value if <code>true</code> then the default PRNG bit stream output
   *          is the same with every invocation of the VM.
   */
  public static final synchronized void setReproducible(final boolean value)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "write"));
    instance().reproducible = value;
    props.put(REPRODUCIBLE_PRNG, String.valueOf(value));
  }

  /**
   * A convenience method to set the global property for checking for weak and
   * semi-weak cipher keys.
   *
   * @param value if <code>true</code> then the cipher implementations will
   *          invoke additional checks for weak and semi-weak key values that
   *          may get generated.
   */
  public static final synchronized void setCheckForWeakKeys(final boolean value)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "write"));
    instance().checkForWeakKeys = value;
    props.put(CHECK_WEAK_KEYS, String.valueOf(value));
  }

  /**
   * A convenience method to set the global property fo adding a blinding
   * operation when executing the RSA decryption primitive.
   *
   * @param value if <code>true</code> then the code for performing the RSA
   *          decryption primitive will include a blinding operation.
   */
  public static final synchronized void setDoRSABlinding(final boolean value)
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "write"));
    instance().doRSABlinding = value;
    props.put(DO_RSA_BLINDING, String.valueOf(value));
  }

  private static final synchronized Properties instance()
  {
    if (singleton == null)
      singleton = new Properties();
    return singleton;
  }

  private void init()
  {
    // default values
    props.put(REPRODUCIBLE_PRNG, (reproducible ? "true" : "false"));
    props.put(CHECK_WEAK_KEYS, (checkForWeakKeys ? "true" : "false"));
    props.put(DO_RSA_BLINDING, (doRSABlinding ? "true" : "false"));
    // 1. allow site-wide override by reading a properties file
    String propFile = null;
    try
      {
        propFile = (String) AccessController.doPrivileged(new PrivilegedAction()
        {
          public Object run()
          {
            return System.getProperty(PROPERTIES_FILE);
          }
        });
      }
    catch (SecurityException se)
      {
        if (Configuration.DEBUG)
          log.fine("Reading property " + PROPERTIES_FILE + " not allowed. Ignored.");
      }
    if (propFile != null)
      {
        try
          {
            final java.util.Properties temp = new java.util.Properties();
            final FileInputStream fin = new FileInputStream(propFile);
            temp.load(fin);
            temp.list(System.out);
            props.putAll(temp);
          }
        catch (IOException ioe)
          {
            if (Configuration.DEBUG)
              log.fine("IO error reading " + propFile + ": " + ioe.getMessage());
          }
        catch (SecurityException se)
          {
            if (Configuration.DEBUG)
              log.fine("Security error reading " + propFile + ": "
                       + se.getMessage());
          }
      }
    // 2. allow vm-specific override by allowing -D options in launcher
    handleBooleanProperty(REPRODUCIBLE_PRNG);
    handleBooleanProperty(CHECK_WEAK_KEYS);
    handleBooleanProperty(DO_RSA_BLINDING);
    // re-sync the 'known' properties
    reproducible = Boolean.valueOf((String) props.get(REPRODUCIBLE_PRNG)).booleanValue();
    checkForWeakKeys = Boolean.valueOf((String) props.get(CHECK_WEAK_KEYS)).booleanValue();
    doRSABlinding = Boolean.valueOf((String) props.get(DO_RSA_BLINDING)).booleanValue();
    // This does not change.
    props.put(VERSION, Registry.VERSION_STRING);
  }

  private void handleBooleanProperty(final String name)
  {
    String s = null;
    try
      {
        s = System.getProperty(name);
      }
    catch (SecurityException x)
      {
        if (Configuration.DEBUG)
          log.fine("SecurityManager forbids reading system properties. Ignored");
      }
    if (s != null)
      {
        s = s.trim().toLowerCase();
        // we have to test for explicit "true" or "false". anything else may
        // hide valid value set previously
        if (s.equals(TRUE) || s.equals(FALSE))
          {
            if (Configuration.DEBUG)
              log.fine("Setting " + name + " to '" + s + "'");
            props.put(name, s);
          }
        else
          {
            if (Configuration.DEBUG)
              log.fine("Invalid value for -D" + name + ": " + s + ". Ignored");
          }
      }
  }
}
