/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

 /*
  * TODO
  * 1. The class extends the PublicKeyImpl class in "org.apache.harmony.security" package.
  *
  * 2. The class uses methods in the auxiliary non-public "ThreeIntegerSequence" class
  *    defined along with the "DSAPrivateKeyImpl" class.
  *
  * 3. See a compatibility with RI comments
  *    in the below "DSAPublicKeyImpl(X509EncodedKeySpec keySpec)" constructor.
  */

package org.apache.harmony.security.provider.crypto;

import java.io.IOException;
import java.io.NotActiveException;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import org.apache.harmony.security.PublicKeyImpl;
import org.apache.harmony.security.asn1.ASN1Integer;
import org.apache.harmony.security.utils.AlgNameMapper;
import org.apache.harmony.security.x509.AlgorithmIdentifier;
import org.apache.harmony.security.x509.SubjectPublicKeyInfo;

/**
 * The class provides DSAPublicKey functionality by extending a class implementing PublicKey
 * and implementing methods defined in both interfaces, DSAKey and DSAPublicKey
 */
public class DSAPublicKeyImpl extends PublicKeyImpl implements DSAPublicKey {

    /**
     * @serial
     */
    private static final long serialVersionUID = -2279672131310978336L;

    private BigInteger y, g, p, q;

    private transient DSAParams params;

    /**
     * Creates object from DSAPublicKeySpec.
     *
     * @param keySpec - a DSAPublicKeySpec object
     */
    public DSAPublicKeyImpl(DSAPublicKeySpec keySpec) {

        super("DSA");

        SubjectPublicKeyInfo spki;

        p = keySpec.getP();
        q = keySpec.getQ();
        g = keySpec.getG();

        ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
                .toByteArray(), q.toByteArray(), g.toByteArray());

        AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper
                .map2OID("DSA"),
                threeInts.getEncoded());

        y = keySpec.getY();

        spki = new SubjectPublicKeyInfo(ai, ASN1Integer.getInstance().encode(
                y.toByteArray()));
        setEncoding(spki.getEncoded());

        params = (DSAParams) (new DSAParameterSpec(p, q, g));
    }

    /**
     * Creates object from X509EncodedKeySpec.
     *
     * @param keySpec - a X509EncodedKeySpec object
     *
     * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format
     */
    public DSAPublicKeyImpl(X509EncodedKeySpec keySpec)
            throws InvalidKeySpecException {

        super("DSA");

        AlgorithmIdentifier ai;
        ThreeIntegerSequence threeInts = null;

        SubjectPublicKeyInfo subjectPublicKeyInfo = null;

        byte[] encoding = keySpec.getEncoded();

        String alg, algName;

        try {
            subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1
                    .decode(encoding);
        } catch (IOException e) {
            throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e);
        }

        try {
            y = new BigInteger((byte[]) ASN1Integer.getInstance().decode(
                    subjectPublicKeyInfo.getSubjectPublicKey()));
        } catch (IOException e) {
            throw new InvalidKeySpecException("Failed to decode parameters: " + e);
        }

        ai = subjectPublicKeyInfo.getAlgorithmIdentifier();

        try {
            threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1
                    .decode(ai.getParameters());
        } catch (IOException e) {
            throw new InvalidKeySpecException("Failed to decode parameters: " + e);
        }
        p = new BigInteger(threeInts.p);
        q = new BigInteger(threeInts.q);
        g = new BigInteger(threeInts.g);
        params = (DSAParams) (new DSAParameterSpec(p, q, g));

        setEncoding(encoding);

        /*
         * the following code implements RI behavior
         */
        alg = ai.getAlgorithm();
        algName = AlgNameMapper.map2AlgName(alg);
        setAlgorithm(algName == null ? alg : algName);
    }

    /**
     * @return
     *      a value of a public key (y).
     */
    public BigInteger getY() {
        return y;
    }

    /**
     * @return
     *     DSA key parameters (p, q, g).
     */
    public DSAParams getParams() {
        return params;
    }

    private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
    	in.defaultReadObject();
    	params = new DSAParameterSpec(p, q, g);
    }

}
