/*
 * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.provider;

import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;

import java.security.*;
import java.security.SecureRandom;
import java.security.interfaces.*;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;

import sun.security.util.Debug;
import sun.security.util.DerValue;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
import sun.security.x509.AlgIdDSA;
import sun.security.jca.JCAUtil;

/**
 * The Digital Signature Standard (using the Digital Signature
 * Algorithm), as described in fips186 of the National Instute of
 * Standards and Technology (NIST), using fips180-1 (SHA-1).
 *
 * This file contains both the signature implementation for the
 * commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS
 * among others. RawDSA expects the 20 byte SHA-1 digest as input
 * via update rather than the original data like other signature
 * implementations.
 *
 * @author Benjamin Renaud
 *
 * @since   1.1
 *
 * @see DSAPublicKey
 * @see DSAPrivateKey
 */
abstract class DSA extends SignatureSpi {

    /* Are we debugging? */
    private static final boolean debug = false;

    /* The parameter object */
    private DSAParams params;

    /* algorithm parameters */
    private BigInteger presetP, presetQ, presetG;

    /* The public key, if any */
    private BigInteger presetY;

    /* The private key, if any */
    private BigInteger presetX;

    /* The random seed used to generate k */
    private int[] Kseed;

    /* The random seed used to generate k (specified by application) */
    private byte[] KseedAsByteArray;

    /*
     * The random seed used to generate k
     * (prevent the same Kseed from being used twice in a row
     */
    private int[] previousKseed;

    /* The RNG used to output a seed for generating k */
    private SecureRandom signingRandom;

    /**
     * Construct a blank DSA object. It must be
     * initialized before being usable for signing or verifying.
     */
    DSA() {
        super();
    }

    /**
     * Return the 20 byte hash value and reset the digest.
     */
    abstract byte[] getDigest() throws SignatureException;

    /**
     * Reset the digest.
     */
    abstract void resetDigest();

    /**
     * Standard SHA1withDSA implementation.
     */
    public static final class SHA1withDSA extends DSA {

        /* The SHA hash for the data */
        private final MessageDigest dataSHA;

        public SHA1withDSA() throws NoSuchAlgorithmException {
            dataSHA = MessageDigest.getInstance("SHA-1");
        }

        /**
         * Update a byte to be signed or verified.
         */
        protected void engineUpdate(byte b) {
            dataSHA.update(b);
        }

        /**
         * Update an array of bytes to be signed or verified.
         */
        protected void engineUpdate(byte[] data, int off, int len) {
            dataSHA.update(data, off, len);
        }

        protected void engineUpdate(ByteBuffer b) {
            dataSHA.update(b);
        }

        byte[] getDigest() {
            return dataSHA.digest();
        }

        void resetDigest() {
            dataSHA.reset();
        }
    }

    /**
     * RawDSA implementation.
     *
     * RawDSA requires the data to be exactly 20 bytes long. If it is
     * not, a SignatureException is thrown when sign()/verify() is called
     * per JCA spec.
     */
    public static final class RawDSA extends DSA {

        // length of the SHA-1 digest (20 bytes)
        private final static int SHA1_LEN = 20;

        // 20 byte digest buffer
        private final byte[] digestBuffer;

        // offset into the buffer
        private int ofs;

        public RawDSA() {
            digestBuffer = new byte[SHA1_LEN];
        }

        protected void engineUpdate(byte b) {
            if (ofs == SHA1_LEN) {
                ofs = SHA1_LEN + 1;
                return;
            }
            digestBuffer[ofs++] = b;
        }

        protected void engineUpdate(byte[] data, int off, int len) {
            if (ofs + len > SHA1_LEN) {
                ofs = SHA1_LEN + 1;
                return;
            }
            System.arraycopy(data, off, digestBuffer, ofs, len);
            ofs += len;
        }

        byte[] getDigest() throws SignatureException {
            if (ofs != SHA1_LEN) {
                throw new SignatureException
                        ("Data for RawDSA must be exactly 20 bytes long");
            }
            ofs = 0;
            return digestBuffer;
        }

        void resetDigest() {
            ofs = 0;
        }
    }

    /**
     * Initialize the DSA object with a DSA private key.
     *
     * @param privateKey the DSA private key
     *
     * @exception InvalidKeyException if the key is not a valid DSA private
     * key.
     */
    protected void engineInitSign(PrivateKey privateKey)
            throws InvalidKeyException {
        if (!(privateKey instanceof java.security.interfaces.DSAPrivateKey)) {
            throw new InvalidKeyException("not a DSA private key: " +
                                          privateKey);
        }
        java.security.interfaces.DSAPrivateKey priv =
            (java.security.interfaces.DSAPrivateKey)privateKey;
        this.presetX = priv.getX();
        this.presetY = null;
        initialize(priv.getParams());
    }

    /**
     * Initialize the DSA object with a DSA public key.
     *
     * @param publicKey the DSA public key.
     *
     * @exception InvalidKeyException if the key is not a valid DSA public
     * key.
     */
    protected void engineInitVerify(PublicKey publicKey)
            throws InvalidKeyException {
        if (!(publicKey instanceof java.security.interfaces.DSAPublicKey)) {
            throw new InvalidKeyException("not a DSA public key: " +
                                          publicKey);
        }
        java.security.interfaces.DSAPublicKey pub =
            (java.security.interfaces.DSAPublicKey)publicKey;
        this.presetY = pub.getY();
        this.presetX = null;
        initialize(pub.getParams());
    }

    private void initialize(DSAParams params) throws InvalidKeyException {
        resetDigest();
        setParams(params);
    }

    /**
     * Sign all the data thus far updated. The signature is formatted
     * according to the Canonical Encoding Rules, returned as a DER
     * sequence of Integer, r and s.
     *
     * @return a signature block formatted according to the Canonical
     * Encoding Rules.
     *
     * @exception SignatureException if the signature object was not
     * properly initialized, or if another exception occurs.
     *
     * @see sun.security.DSA#engineUpdate
     * @see sun.security.DSA#engineVerify
     */
    protected byte[] engineSign() throws SignatureException {
        BigInteger k = generateK(presetQ);
        BigInteger r = generateR(presetP, presetQ, presetG, k);
        BigInteger s = generateS(presetX, presetQ, r, k);

        try {
            DerOutputStream outseq = new DerOutputStream(100);
            outseq.putInteger(r);
            outseq.putInteger(s);
            DerValue result = new DerValue(DerValue.tag_Sequence,
                                           outseq.toByteArray());

            return result.toByteArray();

        } catch (IOException e) {
            throw new SignatureException("error encoding signature");
        }
    }

    /**
     * Verify all the data thus far updated.
     *
     * @param signature the alledged signature, encoded using the
     * Canonical Encoding Rules, as a sequence of integers, r and s.
     *
     * @exception SignatureException if the signature object was not
     * properly initialized, or if another exception occurs.
     *
     * @see sun.security.DSA#engineUpdate
     * @see sun.security.DSA#engineSign
     */
    protected boolean engineVerify(byte[] signature)
            throws SignatureException {
        return engineVerify(signature, 0, signature.length);
    }

    /**
     * Verify all the data thus far updated.
     *
     * @param signature the alledged signature, encoded using the
     * Canonical Encoding Rules, as a sequence of integers, r and s.
     *
     * @param offset the offset to start from in the array of bytes.
     *
     * @param length the number of bytes to use, starting at offset.
     *
     * @exception SignatureException if the signature object was not
     * properly initialized, or if another exception occurs.
     *
     * @see sun.security.DSA#engineUpdate
     * @see sun.security.DSA#engineSign
     */
    protected boolean engineVerify(byte[] signature, int offset, int length)
            throws SignatureException {

        BigInteger r = null;
        BigInteger s = null;
        // first decode the signature.
        try {
            DerInputStream in = new DerInputStream(signature, offset, length);
            DerValue[] values = in.getSequence(2);

            r = values[0].getBigInteger();
            s = values[1].getBigInteger();

        } catch (IOException e) {
            throw new SignatureException("invalid encoding for signature");
        }

        // some implementations do not correctly encode values in the ASN.1
        // 2's complement format. force r and s to be positive in order to
        // to validate those signatures
        if (r.signum() < 0) {
            r = new BigInteger(1, r.toByteArray());
        }
        if (s.signum() < 0) {
            s = new BigInteger(1, s.toByteArray());
        }

        if ((r.compareTo(presetQ) == -1) && (s.compareTo(presetQ) == -1)) {
            BigInteger w = generateW(presetP, presetQ, presetG, s);
            BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r);
            return v.equals(r);
        } else {
            throw new SignatureException("invalid signature: out of range values");
        }
    }

    private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
                         BigInteger k) {
        BigInteger temp = g.modPow(k, p);
        return temp.remainder(q);
   }

    private BigInteger generateS(BigInteger x, BigInteger q,
            BigInteger r, BigInteger k) throws SignatureException {

        byte[] s2 = getDigest();
        BigInteger temp = new BigInteger(1, s2);
        BigInteger k1 = k.modInverse(q);

        BigInteger s = x.multiply(r);
        s = temp.add(s);
        s = k1.multiply(s);
        return s.remainder(q);
    }

    private BigInteger generateW(BigInteger p, BigInteger q,
                         BigInteger g, BigInteger s) {
        return s.modInverse(q);
    }

    private BigInteger generateV(BigInteger y, BigInteger p,
             BigInteger q, BigInteger g, BigInteger w, BigInteger r)
             throws SignatureException {

        byte[] s2 = getDigest();
        BigInteger temp = new BigInteger(1, s2);

        temp = temp.multiply(w);
        BigInteger u1 = temp.remainder(q);

        BigInteger u2 = (r.multiply(w)).remainder(q);

        BigInteger t1 = g.modPow(u1,p);
        BigInteger t2 = y.modPow(u2,p);
        BigInteger t3 = t1.multiply(t2);
        BigInteger t5 = t3.remainder(p);
        return t5.remainder(q);
    }

    /*
     * Please read bug report 4044247 for an alternative, faster,
     * NON-FIPS approved method to generate K
     */
    private BigInteger generateK(BigInteger q) {

        BigInteger k = null;

        // The application specified a Kseed for us to use.
        // Note that we do not allow usage of the same Kseed twice in a row
        if (Kseed != null && !Arrays.equals(Kseed, previousKseed)) {
            k = generateK(Kseed, q);
            if (k.signum() > 0 && k.compareTo(q) < 0) {
                previousKseed = new int [Kseed.length];
                System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length);
                return k;
            }
        }

        // The application did not specify a Kseed for us to use.
        // We'll generate a new Kseed by getting random bytes from
        // a SecureRandom object.
        SecureRandom random = getSigningRandom();

        while (true) {
            int[] seed = new int[5];

            for (int i = 0; i < 5; i++)
                seed[i] = random.nextInt();
            k = generateK(seed, q);
            if (k.signum() > 0 && k.compareTo(q) < 0) {
                previousKseed = new int [seed.length];
                System.arraycopy(seed, 0, previousKseed, 0, seed.length);
                return k;
            }
        }
    }

    // Use the application-specified SecureRandom Object if provided.
    // Otherwise, use our default SecureRandom Object.
    private SecureRandom getSigningRandom() {
        if (signingRandom == null) {
            if (appRandom != null) {
                signingRandom = appRandom;
            } else {
                signingRandom = JCAUtil.getSecureRandom();
            }
        }
        return signingRandom;
    }

    /**
     * Compute k for a DSA signature.
     *
     * @param seed the seed for generating k. This seed should be
     * secure. This is what is refered to as the KSEED in the DSA
     * specification.
     *
     * @param g the g parameter from the DSA key pair.
     */
    private BigInteger generateK(int[] seed, BigInteger q) {

        // check out t in the spec.
        int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
                    0xC3D2E1F0, 0x67452301 };
        //
        int[] tmp = DSA.SHA_7(seed, t);
        byte[] tmpBytes = new byte[tmp.length * 4];
        for (int i = 0; i < tmp.length; i++) {
            int k = tmp[i];
            for (int j = 0; j < 4; j++) {
                tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
            }
        }
        BigInteger k = new BigInteger(1, tmpBytes).mod(q);
        return k;
    }

   // Constants for each round
    private static final int round1_kt = 0x5a827999;
    private static final int round2_kt = 0x6ed9eba1;
    private static final int round3_kt = 0x8f1bbcdc;
    private static final int round4_kt = 0xca62c1d6;

   /**
    * Computes set 1 thru 7 of SHA-1 on m1. */
   static int[] SHA_7(int[] m1, int[] h) {

       int[] W = new int[80];
       System.arraycopy(m1,0,W,0,m1.length);
       int temp = 0;

        for (int t = 16; t <= 79; t++){
            temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
            W[t] = ((temp << 1) | (temp >>>(32 - 1)));
        }

       int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
       for (int i = 0; i < 20; i++) {
            temp = ((a<<5) | (a>>>(32-5))) +
                ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
            e = d;
            d = c;
            c = ((b<<30) | (b>>>(32-30)));
            b = a;
            a = temp;
        }

        // Round 2
        for (int i = 20; i < 40; i++) {
            temp = ((a<<5) | (a>>>(32-5))) +
                (b ^ c ^ d) + e + W[i] + round2_kt;
            e = d;
            d = c;
            c = ((b<<30) | (b>>>(32-30)));
            b = a;
            a = temp;
        }

        // Round 3
        for (int i = 40; i < 60; i++) {
            temp = ((a<<5) | (a>>>(32-5))) +
                ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
            e = d;
            d = c;
            c = ((b<<30) | (b>>>(32-30)));
            b = a;
            a = temp;
        }

        // Round 4
        for (int i = 60; i < 80; i++) {
            temp = ((a<<5) | (a>>>(32-5))) +
                (b ^ c ^ d) + e + W[i] + round4_kt;
            e = d;
            d = c;
            c = ((b<<30) | (b>>>(32-30)));
            b = a;
            a = temp;
        }
       int[] md = new int[5];
       md[0] = h[0] + a;
       md[1] = h[1] + b;
       md[2] = h[2] + c;
       md[3] = h[3] + d;
       md[4] = h[4] + e;
       return md;
   }


    /**
     * This implementation recognizes the following parameter:<dl>
     *
     * <dt><tt>Kseed</tt>
     *
     * <dd>a byte array.
     *
     * </dl>
     *
     * @deprecated
     */
    @Deprecated
    protected void engineSetParameter(String key, Object param) {
        if (key.equals("KSEED")) {
            if (param instanceof byte[]) {
                Kseed = byteArray2IntArray((byte[])param);
                KseedAsByteArray = (byte[])param;
            } else {
                debug("unrecognized param: " + key);
                throw new InvalidParameterException("Kseed not a byte array");
            }
        } else {
            throw new InvalidParameterException("invalid parameter");
        }
    }

    /**
     * Return the value of the requested parameter. Recognized
     * parameters are:
     *
     * <dl>
     *
     * <dt><tt>Kseed</tt>
     *
     * <dd>a byte array.
     *
     * </dl>
     *
     * @return the value of the requested parameter.
     *
     * @see java.security.SignatureEngine
     *
     * @deprecated
     */
    @Deprecated
    protected Object engineGetParameter(String key) {
        if (key.equals("KSEED")) {
            return KseedAsByteArray;
        } else {
            return null;
        }
    }

    /**
     * Set the algorithm object.
     */
    private void setParams(DSAParams params) throws InvalidKeyException {
        if (params == null) {
            throw new InvalidKeyException("DSA public key lacks parameters");
        }
        this.params = params;
        this.presetP = params.getP();
        this.presetQ = params.getQ();
        this.presetG = params.getG();
    }

    /**
     * Return a human readable rendition of the engine.
     */
    public String toString() {
        String printable = "DSA Signature";
        if (presetP != null && presetQ != null && presetG != null) {
            printable += "\n\tp: " + Debug.toHexString(presetP);
            printable += "\n\tq: " + Debug.toHexString(presetQ);
            printable += "\n\tg: " + Debug.toHexString(presetG);
        } else {
            printable += "\n\t P, Q or G not initialized.";
        }
        if (presetY != null) {
            printable += "\n\ty: " + Debug.toHexString(presetY);
        }
        if (presetY == null && presetX == null) {
            printable += "\n\tUNINIIALIZED";
        }
        return printable;
    }

    /*
     * Utility routine for converting a byte array into an int array
     */
    private int[] byteArray2IntArray(byte[] byteArray) {

        int j = 0;
        byte[] newBA;
        int mod = byteArray.length % 4;

        // guarantee that the incoming byteArray is a multiple of 4
        // (pad with 0's)
        switch (mod) {
            case 3:     newBA = new byte[byteArray.length + 1]; break;
            case 2:     newBA = new byte[byteArray.length + 2]; break;
            case 1:     newBA = new byte[byteArray.length + 3]; break;
            default:    newBA = new byte[byteArray.length + 0]; break;
        }
        System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);

        // copy each set of 4 bytes in the byte array into an integer
        int[] newSeed = new int[newBA.length / 4];
        for (int i = 0; i < newBA.length; i += 4) {
            newSeed[j] = newBA[i + 3] & 0xFF;
            newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
            newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
            newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
            j++;
        }

        return newSeed;
    }

    private static void debug(Exception e) {
        if (debug) {
            e.printStackTrace();
        }
    }

    private static void debug(String s) {
        if (debug) {
            System.err.println(s);
        }
    }
}
