/* KeyPairCodecFactory.java -- 
   Copyright 2001, 2002, 2006 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.key;

import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec;
import gnu.java.security.key.dss.DSSKeyPairRawCodec;
import gnu.java.security.key.dss.DSSKeyPairX509Codec;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec;
import gnu.java.security.key.rsa.RSAKeyPairRawCodec;
import gnu.java.security.key.rsa.RSAKeyPairX509Codec;
import gnu.java.security.util.FormatUtil;

import java.lang.reflect.Constructor;
import java.security.Key;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * A <i>Factory</i> class to instantiate key encoder/decoder instances.
 */
public class KeyPairCodecFactory
{
  private static Set names;

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

  /**
   * Returns the appropriate codec given a composed key-pair generator algorithm
   * and an encoding format. A composed name is formed by the concatenation of
   * the canonical key-pair algorithm name, the forward slash character
   * <code>/</code> and the canonical name of the encoding format.
   * <p>
   * <b>IMPORTANT</b>: For backward compatibility, when the encoding format
   * name is missing, the Raw encoding format is assumed. When this is the case
   * the trailing forward slash is discarded from the name.
   * 
   * @param name the case-insensitive key codec name.
   * @return an instance of the keypair codec, or <code>null</code> if none
   *         found.
   */
  public static IKeyPairCodec getInstance(String name)
  {
    if (name == null)
      return null;

    name = name.trim();
    if (name.length() == 0)
      return null;

    if (name.startsWith("/"))
      return null;

    if (name.endsWith("/"))
      return getInstance(name.substring(0, name.length() - 1),
                         Registry.RAW_ENCODING_ID);

    int i = name.indexOf("/");
    if (i == -1)
      return getInstance(name, Registry.RAW_ENCODING_ID);

    String kpgName = name.substring(0, i);
    String formatName = name.substring(i + 1);
    return getInstance(kpgName, formatName);
  }

  /**
   * Returns an instance of a keypair codec given the canonical name of the
   * key-pair algorithm, and the name of the encoding format to use when
   * externalizing the keys.
   * 
   * @param name the case-insensitive key-pair algorithm name.
   * @param format the name of the encoding format to use when externalizing the
   *          keys generated by the key-pair algorithm.
   * @return an instance of the key-pair codec, or <code>null</code> if none
   *         found.
   */
  public static IKeyPairCodec getInstance(String name, String format)
  {
    int formatID = FormatUtil.getFormatID(format);
    if (formatID == 0)
      return null;

    return getInstance(name, formatID);
  }

  /**
   * Returns an instance of a keypair codec given the canonical name of the
   * key-pair algorithm, and the identifier of the format to use when
   * externalizing the keys.
   * 
   * @param name the case-insensitive key-pair algorithm name.
   * @param formatID the identifier of the format to use when externalizing the
   *          keys generated by the key-pair algorithm.
   * @return an instance of the key-pair codec, or <code>null</code> if none
   *         found.
   */
  public static IKeyPairCodec getInstance(String name, int formatID)
  {
    if (name == null)
      return null;

    name = name.trim();
    switch (formatID)
      {
      case Registry.RAW_ENCODING_ID:
        return getRawCodec(name);
      case Registry.X509_ENCODING_ID:
        return getX509Codec(name);
      case Registry.PKCS8_ENCODING_ID:
        return getPKCS8Codec(name);
      }

    return null;
  }

  /**
   * Returns an instance of a keypair codec given a key.
   * 
   * @param key the key to encode.
   * @return an instance of the keypair codec, or <code>null</code> if none
   *         found.
   */
  public static IKeyPairCodec getInstance(Key key)
  {
    if (key == null)
      return null;

    String format = key.getFormat();
    int formatID = FormatUtil.getFormatID(format);
    if (formatID == 0)
      return null;

    switch (formatID)
      {
      case Registry.RAW_ENCODING_ID:
        return getRawCodec(key);
      case Registry.X509_ENCODING_ID:
        return getX509Codec(key);
      case Registry.PKCS8_ENCODING_ID:
        return getPKCS8Codec(key);
      }

    return null;
  }

  /**
   * Returns a {@link Set} of supported key-pair codec names.
   *
   * @return a {@link Set} of the names of supported key-pair codec (Strings).
   */
  public static synchronized final Set getNames()
  {
    if (names == null)
      {
        HashSet hs = new HashSet();
        hs.add(Registry.DSS_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
        hs.add(Registry.DSS_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
        hs.add(Registry.DSS_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
        hs.add(Registry.RSA_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
        hs.add(Registry.RSA_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
        hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
        hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
        hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
        names = Collections.unmodifiableSet(hs);
      }
    return names;
  }

  private static IKeyPairCodec makeInstance (String clazz)
  {
    try
      {
        Class c = Class.forName (clazz);
        Constructor ctor = c.getConstructor (new Class[0]);
        return (IKeyPairCodec) ctor.newInstance (new Object[0]);
      }
    catch (Exception x)
      {
        IllegalArgumentException iae =
          new IllegalArgumentException ("strong crypto key codec not available: "
                                        + clazz);
        iae.initCause (x);
        throw iae;
      }
  }

  private static boolean matches (Object o, String clazz)
  {
    try
      {
        Class c = Class.forName (clazz);
        return c.isAssignableFrom (o.getClass ());
      }
    catch (Exception x)
      {
        // Can't match.
        return false;
      }
  }

  /**
   * @param name the trimmed name of a key-pair algorithm.
   * @return a Raw format codec for the designated key-pair algorithm, or
   *         <code>null</code> if none exists.
   */
  private static IKeyPairCodec getRawCodec(String name)
  {
    IKeyPairCodec result = null;
    if (name.equalsIgnoreCase(Registry.DSA_KPG)
        || name.equals(Registry.DSS_KPG))
      result = new DSSKeyPairRawCodec();
    else if (name.equalsIgnoreCase(Registry.RSA_KPG))
      result = new RSAKeyPairRawCodec();
    else if (name.equalsIgnoreCase(Registry.DH_KPG))
      result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
    else if (name.equalsIgnoreCase(Registry.SRP_KPG))
      result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");

    return result;
  }

  /**
   * @param name the trimmed name of a key-pair algorithm.
   * @return a X.509 format codec for the designated key-pair algorithm, or
   *         <code>null</code> if none exists.
   */
  private static IKeyPairCodec getX509Codec(String name)
  {
    IKeyPairCodec result = null;
    if (name.equalsIgnoreCase(Registry.DSA_KPG)
        || name.equals(Registry.DSS_KPG))
      result = new DSSKeyPairX509Codec();
    else if (name.equalsIgnoreCase(Registry.RSA_KPG))
      result = new RSAKeyPairX509Codec();
    else if (name.equalsIgnoreCase(Registry.DH_KPG))
      result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairX509Codec");

    return result;
  }

  /**
   * @param name the trimmed name of a key-pair algorithm.
   * @return a PKCS#8 format codec for the designated key-pair algorithm, or
   *         <code>null</code> if none exists.
   */
  private static IKeyPairCodec getPKCS8Codec(String name)
  {
    IKeyPairCodec result = null;
    if (name.equalsIgnoreCase(Registry.DSA_KPG)
        || name.equals(Registry.DSS_KPG))
      result = new DSSKeyPairPKCS8Codec();
    else if (name.equalsIgnoreCase(Registry.RSA_KPG))
      result = new RSAKeyPairPKCS8Codec();
    else if (name.equalsIgnoreCase(Registry.DH_KPG))
      result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairPKCS8Codec");

    return result;
  }

  /**
   * @param key a {@link Key} for which we want to return a Raw codec.
   * @return the Raw codec corresponding to the key, or <code>null</code> if
   *         none exists for this key.
   */
  private static IKeyPairCodec getRawCodec(Key key)
  {
    IKeyPairCodec result = null;
    if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey))
      result = new DSSKeyPairRawCodec();
    else if ((key instanceof GnuRSAPublicKey)
             || (key instanceof GnuRSAPrivateKey))
      result = new RSAKeyPairRawCodec();
    else if (matches(key, "gnu.javax.crypto.key.dh.GnuDHPublicKey")
             || matches(key, "gnu.javax.crypto.key.dh.GnuDHPrivateKey"))
      result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
    else if (matches(key, "gnu.javax.crypto.key.srp6.SRPPublicKey")
             || matches(key, "gnu.javax.crypto.key.srp6.SRPPrivateKey"))
      result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");

    return result;
  }

  /**
   * @param key a {@link Key} for which we want to return an X.509 codec.
   * @return the X.509 codec corresponding to the key, or <code>null</code> if
   *         none exists for this key.
   */
  private static IKeyPairCodec getX509Codec(Key key)
  {
    IKeyPairCodec result = null;
    if (key instanceof DSSPublicKey)
      result = new DSSKeyPairX509Codec();
    else if (key instanceof GnuRSAPublicKey)
      result = new RSAKeyPairX509Codec();

    return result;
  }

  /**
   * @param key a {@link Key} for which we want to return a PKCS#8 codec.
   * @return the PKCS#8 codec corresponding to the key, or <code>null</code> if
   *         none exists for this key.
   */
  private static IKeyPairCodec getPKCS8Codec(Key key)
  {
    IKeyPairCodec result = null;
    if (key instanceof DSSPrivateKey)
      result = new DSSKeyPairPKCS8Codec();
    else if (key instanceof GnuRSAPrivateKey)
      result = new RSAKeyPairPKCS8Codec();

    return result;
  }
}
