/* PrivateCredentials.java -- private key/certificate pairs.
   Copyright (C) 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.javax.net.ssl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;

import java.math.BigInteger;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import javax.net.ssl.ManagerFactoryParameters;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

import gnu.javax.security.auth.callback.ConsoleCallbackHandler;
import gnu.java.security.hash.HashFactory;
import gnu.java.security.hash.IMessageDigest;
import gnu.javax.crypto.mode.IMode;
import gnu.javax.crypto.mode.ModeFactory;
import gnu.javax.crypto.pad.WrongPaddingException;

import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;

/**
 * An instance of a manager factory parameters for holding a single
 * certificate/private key pair, encoded in PEM format.
 */
public class PrivateCredentials implements ManagerFactoryParameters
{

  // Fields.
  // -------------------------------------------------------------------------

  public static final String BEGIN_DSA = "-----BEGIN DSA PRIVATE KEY";
  public static final String END_DSA   = "-----END DSA PRIVATE KEY";
  public static final String BEGIN_RSA = "-----BEGIN RSA PRIVATE KEY";
  public static final String END_RSA   = "-----END RSA PRIVATE KEY";

  private List privateKeys;
  private List certChains;

  // Constructor.
  // -------------------------------------------------------------------------

  public PrivateCredentials()
  {
    privateKeys = new LinkedList();
    certChains = new LinkedList();
  }

  // Instance methods.
  // -------------------------------------------------------------------------

  public void add(InputStream certChain, InputStream privateKey)
    throws CertificateException, InvalidKeyException, InvalidKeySpecException,
           IOException, NoSuchAlgorithmException, WrongPaddingException
  {
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    Collection certs = cf.generateCertificates(certChain);
    X509Certificate[] chain = (X509Certificate[]) certs.toArray(new X509Certificate[0]);

    String alg = null;
    String line = readLine(privateKey);
    String finalLine = null;
    if (line.startsWith(BEGIN_DSA))
      {
        alg = "DSA";
        finalLine = END_DSA;
      }
    else if (line.startsWith(BEGIN_RSA))
      {
        alg = "RSA";
        finalLine = END_RSA;
      }
    else
      throw new IOException("Unknown private key type.");

    boolean encrypted = false;
    String cipher = null;
    String salt = null;
    StringBuffer base64 = new StringBuffer();
    while (true)
      {
        line = readLine(privateKey);
        if (line == null)
          throw new EOFException("premature end-of-file");
        else if (line.startsWith("Proc-Type: 4,ENCRYPTED"))
          encrypted = true;
        else if (line.startsWith("DEK-Info: "))
          {
            int i = line.indexOf(',');
            if (i < 0)
              cipher = line.substring(10).trim();
            else
              {
                cipher = line.substring(10, i).trim();
                salt = line.substring(i + 1).trim();
              }
          }
        else if (line.startsWith(finalLine))
          break;
        else if (line.length() > 0)
          {
            base64.append(line);
            base64.append(System.getProperty("line.separator"));
          }
      }

    byte[] enckey = Base64.decode(base64.toString());
    if (encrypted)
      {
        enckey = decryptKey(enckey, cipher, toByteArray(salt));
      }

    DERReader der = new DERReader(enckey);
    if (der.read().getTag() != DER.SEQUENCE)
      throw new IOException("malformed DER sequence");
    der.read(); // version

    KeyFactory kf = KeyFactory.getInstance(alg);
    KeySpec spec = null;
    if (alg.equals("DSA"))
      {
        BigInteger p = (BigInteger) der.read().getValue();
        BigInteger q = (BigInteger) der.read().getValue();
        BigInteger g = (BigInteger) der.read().getValue();
        der.read(); // y
        BigInteger x = (BigInteger) der.read().getValue();
        spec = new DSAPrivateKeySpec(x, p, q, g);
      }
    else
      {
        spec = new RSAPrivateCrtKeySpec(
          (BigInteger) der.read().getValue(),  // modulus
          (BigInteger) der.read().getValue(),  // pub exponent
          (BigInteger) der.read().getValue(),  // priv expenent
          (BigInteger) der.read().getValue(),  // prime p
          (BigInteger) der.read().getValue(),  // prime q
          (BigInteger) der.read().getValue(),  // d mod (p-1)
          (BigInteger) der.read().getValue(),  // d mod (q-1)
          (BigInteger) der.read().getValue()); // coefficient
      }
    privateKeys.add(kf.generatePrivate(spec));
    certChains.add(chain);
  }

  public List getPrivateKeys()
  {
    if (isDestroyed())
      {
        throw new IllegalStateException("this object is destroyed");
      }
    return privateKeys;
  }

  public List getCertChains()
  {
    return certChains;
  }

  public void destroy()
  {
    privateKeys.clear();
    privateKeys = null;
  }

  public boolean isDestroyed()
  {
    return (privateKeys == null);
  }

  // Own methods.
  // -------------------------------------------------------------------------

  private String readLine(InputStream in) throws IOException
  {
    boolean eol_is_cr = System.getProperty("line.separator").equals("\r");
    StringBuffer str = new StringBuffer();
    while (true)
      {
        int i = in.read();
        if (i == -1)
          {
            if (str.length() > 0)
              break;
            else
              return null;
          }
        else if (i == '\r')
          {
            if (eol_is_cr)
              break;
          }
        else if (i == '\n')
          break;
        else
          str.append((char) i);
      }
    return str.toString();
  }

  private byte[] decryptKey(byte[] ct, String cipher, byte[] salt)
    throws IOException, InvalidKeyException, WrongPaddingException
  {
    byte[] pt = new byte[ct.length];
    IMode mode = null;
    if (cipher.equals("DES-EDE3-CBC"))
      {
        mode = ModeFactory.getInstance("CBC", "TripleDES", 8);
        HashMap attr = new HashMap();
        attr.put(IMode.KEY_MATERIAL, deriveKey(salt, 24));
        attr.put(IMode.IV, salt);
        attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
        mode.init(attr);
      }
    else if (cipher.equals("DES-CBC"))
      {
        mode = ModeFactory.getInstance("CBC", "DES", 8);
        HashMap attr = new HashMap();
        attr.put(IMode.KEY_MATERIAL, deriveKey(salt, 8));
        attr.put(IMode.IV, salt);
        attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
        mode.init(attr);
      }
    else
      throw new IllegalArgumentException("unknown cipher: " + cipher);

    for (int i = 0; i < ct.length; i += 8)
      mode.update(ct, i, pt, i);

    int pad = pt[pt.length-1];
    if (pad < 1 || pad > 8)
      throw new WrongPaddingException();
    for (int i = pt.length - pad; i < pt.length; i++)
      {
        if (pt[i] != pad)
          throw new WrongPaddingException();
      }

    byte[] result = new byte[pt.length - pad];
    System.arraycopy(pt, 0, result, 0, result.length);
    return result;
  }

  private byte[] deriveKey(byte[] salt, int keylen)
    throws IOException
  {
    CallbackHandler passwordHandler = new ConsoleCallbackHandler();
    try
      {
        Class c = Class.forName(Security.getProperty("jessie.password.handler"));
        passwordHandler = (CallbackHandler) c.newInstance();
      }
    catch (Exception x) { }

    PasswordCallback passwdCallback =
      new PasswordCallback("Enter PEM passphrase: ", false);
    try
      {
        passwordHandler.handle(new Callback[] { passwdCallback });
      }
    catch (UnsupportedCallbackException uce)
      {
        throw new IOException("specified handler cannot handle passwords");
      }
    char[] passwd = passwdCallback.getPassword();

    IMessageDigest md5 = HashFactory.getInstance("MD5");
    byte[] key = new byte[keylen];
    int count = 0;
    while (count < keylen)
      {
        for (int i = 0; i < passwd.length; i++)
          md5.update((byte) passwd[i]);
        md5.update(salt, 0, salt.length);
        byte[] digest = md5.digest();
        int len = Math.min(digest.length, keylen - count);
        System.arraycopy(digest, 0, key, count, len);
        count += len;
        if (count >= keylen)
          break;
        md5.reset();
        md5.update(digest, 0, digest.length);
      }
    passwdCallback.clearPassword();
    return key;
  }

  private byte[] toByteArray(String hex)
  {
    hex = hex.toLowerCase();
    byte[] buf = new byte[hex.length() / 2];
    int j = 0;
    for (int i = 0; i < buf.length; i++)
      {
        buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
                          Character.digit(hex.charAt(j++), 16));
      }
    return buf;
  }
}
