/*
 * Copyright (c) 1997, 2013, 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 javax.crypto;

import java.io.*;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * This class enables a programmer to create an object and protect its
 * confidentiality with a cryptographic algorithm.
 *
 * <p> Given any Serializable object, one can create a SealedObject
 * that encapsulates the original object, in serialized
 * format (i.e., a "deep copy"), and seals (encrypts) its serialized contents,
 * using a cryptographic algorithm such as DES, to protect its
 * confidentiality.  The encrypted content can later be decrypted (with
 * the corresponding algorithm using the correct decryption key) and
 * de-serialized, yielding the original object.
 *
 * <p> Note that the Cipher object must be fully initialized with the
 * correct algorithm, key, padding scheme, etc., before being applied
 * to a SealedObject.
 *
 * <p> The original object that was sealed can be recovered in two different
 * ways:
 *
 * <ul>
 *
 * <li>by using the {@link #getObject(javax.crypto.Cipher) getObject}
 * method that takes a <code>Cipher</code> object.
 *
 * <p> This method requires a fully initialized <code>Cipher</code> object,
 * initialized with the
 * exact same algorithm, key, padding scheme, etc., that were used to seal the
 * object.
 *
 * <p> This approach has the advantage that the party who unseals the
 * sealed object does not require knowledge of the decryption key. For example,
 * after one party has initialized the cipher object with the required
 * decryption key, it could hand over the cipher object to
 * another party who then unseals the sealed object.
 *
 * <li>by using one of the
 * {@link #getObject(java.security.Key) getObject} methods
 * that take a <code>Key</code> object.
 *
 * <p> In this approach, the <code>getObject</code> method creates a cipher
 * object for the appropriate decryption algorithm and initializes it with the
 * given decryption key and the algorithm parameters (if any) that were stored
 * in the sealed object.
 *
 * <p> This approach has the advantage that the party who
 * unseals the object does not need to keep track of the parameters (e.g., an
 * IV) that were used to seal the object.
 *
 * </ul>
 *
 * @author Li Gong
 * @author Jan Luehe
 * @see Cipher
 * @since 1.4
 */

public class SealedObject implements Serializable {

    static final long serialVersionUID = 4482838265551344752L;

    /**
     * The serialized object contents in encrypted format.
     *
     * @serial
     */
    private byte[] encryptedContent = null;

    /**
     * The algorithm that was used to seal this object.
     *
     * @serial
     */
    private String sealAlg = null;

    /**
     * The algorithm of the parameters used.
     *
     * @serial
     */
    private String paramsAlg = null;

    /**
     * The cryptographic parameters used by the sealing Cipher,
     * encoded in the default format.
     * <p>
     * That is, <code>cipher.getParameters().getEncoded()</code>.
     *
     * @serial
     */
    protected byte[] encodedParams = null;

    /**
     * Constructs a SealedObject from any Serializable object.
     *
     * <p>The given object is serialized, and its serialized contents are
     * encrypted using the given Cipher, which must be fully initialized.
     *
     * <p>Any algorithm parameters that may be used in the encryption
     * operation are stored inside of the new <code>SealedObject</code>.
     *
     * @param object the object to be sealed; can be null.
     * @param c the cipher used to seal the object.
     *
     * @exception NullPointerException if the given cipher is null.
     * @exception IOException if an error occurs during serialization
     * @exception IllegalBlockSizeException if the given cipher is a block
     * cipher, no padding has been requested, and the total input length
     * (i.e., the length of the serialized object contents) is not a multiple
     * of the cipher's block size
     */
    public SealedObject(Serializable object, Cipher c) throws IOException,
        IllegalBlockSizeException
    {
        /*
         * Serialize the object
         */

        // creating a stream pipe-line, from a to b
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutput a = new ObjectOutputStream(b);
        byte[] content;
        try {
            // write and flush the object content to byte array
            a.writeObject(object);
            a.flush();
            content = b.toByteArray();
        } finally {
            a.close();
        }

        /*
         * Seal the object
         */
        try {
            this.encryptedContent = c.doFinal(content);
        }
        catch (BadPaddingException ex) {
            // if sealing is encryption only
            // Should never happen??
        }

        // Save the parameters
        if (c.getParameters() != null) {
            this.encodedParams = c.getParameters().getEncoded();
            this.paramsAlg = c.getParameters().getAlgorithm();
        }

        // Save the encryption algorithm
        this.sealAlg = c.getAlgorithm();
    }

    /**
     * Constructs a SealedObject object from the passed-in SealedObject.
     *
     * @param so a SealedObject object
     * @exception NullPointerException if the given sealed object is null.
     */
    protected SealedObject(SealedObject so) {
        this.encryptedContent = so.encryptedContent.clone();
        this.sealAlg = so.sealAlg;
        this.paramsAlg = so.paramsAlg;
        if (so.encodedParams != null) {
            this.encodedParams = so.encodedParams.clone();
        } else {
            this.encodedParams = null;
        }
    }

    /**
     * Returns the algorithm that was used to seal this object.
     *
     * @return the algorithm that was used to seal this object.
     */
    public final String getAlgorithm() {
        return this.sealAlg;
    }

    /**
     * Retrieves the original (encapsulated) object.
     *
     * <p>This method creates a cipher for the algorithm that had been used in
     * the sealing operation.
     * If the default provider package provides an implementation of that
     * algorithm, an instance of Cipher containing that implementation is used.
     * If the algorithm is not available in the default package, other
     * packages are searched.
     * The Cipher object is initialized for decryption, using the given
     * <code>key</code> and the parameters (if any) that had been used in the
     * sealing operation.
     *
     * <p>The encapsulated object is unsealed and de-serialized, before it is
     * returned.
     *
     * @param key the key used to unseal the object.
     *
     * @return the original object.
     *
     * @exception IOException if an error occurs during de-serialiazation.
     * @exception ClassNotFoundException if an error occurs during
     * de-serialiazation.
     * @exception NoSuchAlgorithmException if the algorithm to unseal the
     * object is not available.
     * @exception InvalidKeyException if the given key cannot be used to unseal
     * the object (e.g., it has the wrong algorithm).
     * @exception NullPointerException if <code>key</code> is null.
     */
    public final Object getObject(Key key)
        throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
            InvalidKeyException
    {
        if (key == null) {
            throw new NullPointerException("key is null");
        }

        try {
            return unseal(key, null);
        } catch (NoSuchProviderException nspe) {
            // we've already caught NoSuchProviderException's and converted
            // them into NoSuchAlgorithmException's with details about
            // the failing algorithm
            throw new NoSuchAlgorithmException("algorithm not found");
        } catch (IllegalBlockSizeException ibse) {
            throw new InvalidKeyException(ibse.getMessage());
        } catch (BadPaddingException bpe) {
            throw new InvalidKeyException(bpe.getMessage());
        }
    }

    /**
     * Retrieves the original (encapsulated) object.
     *
     * <p>The encapsulated object is unsealed (using the given Cipher,
     * assuming that the Cipher is already properly initialized) and
     * de-serialized, before it is returned.
     *
     * @param c the cipher used to unseal the object
     *
     * @return the original object.
     *
     * @exception NullPointerException if the given cipher is null.
     * @exception IOException if an error occurs during de-serialiazation
     * @exception ClassNotFoundException if an error occurs during
     * de-serialiazation
     * @exception IllegalBlockSizeException if the given cipher is a block
     * cipher, no padding has been requested, and the total input length is
     * not a multiple of the cipher's block size
     * @exception BadPaddingException if the given cipher has been
     * initialized for decryption, and padding has been specified, but
     * the input data does not have proper expected padding bytes
     */
    public final Object getObject(Cipher c)
        throws IOException, ClassNotFoundException, IllegalBlockSizeException,
            BadPaddingException
    {
        /*
         * Unseal the object
         */
        byte[] content = c.doFinal(this.encryptedContent);

        /*
         * De-serialize it
         */
        // creating a stream pipe-line, from b to a
        ByteArrayInputStream b = new ByteArrayInputStream(content);
        ObjectInput a = new extObjectInputStream(b);
        try {
            Object obj = a.readObject();
            return obj;
        } finally {
            a.close();
        }
    }

    /**
     * Retrieves the original (encapsulated) object.
     *
     * <p>This method creates a cipher for the algorithm that had been used in
     * the sealing operation, using an implementation of that algorithm from
     * the given <code>provider</code>.
     * The Cipher object is initialized for decryption, using the given
     * <code>key</code> and the parameters (if any) that had been used in the
     * sealing operation.
     *
     * <p>The encapsulated object is unsealed and de-serialized, before it is
     * returned.
     *
     * @param key the key used to unseal the object.
     * @param provider the name of the provider of the algorithm to unseal
     * the object.
     *
     * @return the original object.
     *
     * @exception IllegalArgumentException if the given provider is null
     * or empty.
     * @exception IOException if an error occurs during de-serialiazation.
     * @exception ClassNotFoundException if an error occurs during
     * de-serialiazation.
     * @exception NoSuchAlgorithmException if the algorithm to unseal the
     * object is not available.
     * @exception NoSuchProviderException if the given provider is not
     * configured.
     * @exception InvalidKeyException if the given key cannot be used to unseal
     * the object (e.g., it has the wrong algorithm).
     * @exception NullPointerException if <code>key</code> is null.
     */
    public final Object getObject(Key key, String provider)
        throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
            NoSuchProviderException, InvalidKeyException
    {
        if (key == null) {
            throw new NullPointerException("key is null");
        }
        if (provider == null || provider.length() == 0) {
            throw new IllegalArgumentException("missing provider");
        }

        try {
            return unseal(key, provider);
        } catch (IllegalBlockSizeException | BadPaddingException ex) {
            throw new InvalidKeyException(ex.getMessage());
        }
    }


    private Object unseal(Key key, String provider)
        throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
            NoSuchProviderException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException
    {
        /*
         * Create the parameter object.
         */
        AlgorithmParameters params = null;
        if (this.encodedParams != null) {
            try {
                if (provider != null)
                    params = AlgorithmParameters.getInstance(this.paramsAlg,
                                                             provider);
                else
                    params = AlgorithmParameters.getInstance(this.paramsAlg);

            } catch (NoSuchProviderException nspe) {
                if (provider == null) {
                    throw new NoSuchAlgorithmException(this.paramsAlg
                                                       + " not found");
                } else {
                    throw new NoSuchProviderException(nspe.getMessage());
                }
            }
            params.init(this.encodedParams);
        }

        /*
         * Create and initialize the cipher.
         */
        Cipher c;
        try {
            if (provider != null)
                c = Cipher.getInstance(this.sealAlg, provider);
            else
                c = Cipher.getInstance(this.sealAlg);
        } catch (NoSuchPaddingException nspe) {
            throw new NoSuchAlgorithmException("Padding that was used in "
                                               + "sealing operation not "
                                               + "available");
        } catch (NoSuchProviderException nspe) {
            if (provider == null) {
                throw new NoSuchAlgorithmException(this.sealAlg+" not found");
            } else {
                throw new NoSuchProviderException(nspe.getMessage());
            }
        }

        try {
            if (params != null)
                c.init(Cipher.DECRYPT_MODE, key, params);
            else
                c.init(Cipher.DECRYPT_MODE, key);
        } catch (InvalidAlgorithmParameterException iape) {
            // this should never happen, because we use the exact same
            // parameters that were used in the sealing operation
            throw new RuntimeException(iape.getMessage());
        }

        /*
         * Unseal the object
         */
        byte[] content = c.doFinal(this.encryptedContent);

        /*
         * De-serialize it
         */
        // creating a stream pipe-line, from b to a
        ByteArrayInputStream b = new ByteArrayInputStream(content);
        ObjectInput a = new extObjectInputStream(b);
        try {
            Object obj = a.readObject();
            return obj;
        } finally {
            a.close();
        }
    }

    /**
     * Restores the state of the SealedObject from a stream.
     * @param s the object input stream.
     * @exception NullPointerException if s is null.
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException
    {
        s.defaultReadObject();
        if (encryptedContent != null)
            encryptedContent = encryptedContent.clone();
        if (encodedParams != null)
            encodedParams = encodedParams.clone();
    }
}

final class extObjectInputStream extends ObjectInputStream {

    private static ClassLoader systemClassLoader = null;

    extObjectInputStream(InputStream in)
        throws IOException, StreamCorruptedException {
        super(in);
    }

    protected Class<?> resolveClass(ObjectStreamClass v)
        throws IOException, ClassNotFoundException
    {

        try {
            /*
             * Calling the super.resolveClass() first
             * will let us pick up bug fixes in the super
             * class (e.g., 4171142).
             */
            return super.resolveClass(v);
        } catch (ClassNotFoundException cnfe) {
            /*
             * This is a workaround for bug 4224921.
             */
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            if (loader == null) {
                if (systemClassLoader == null) {
                    systemClassLoader = ClassLoader.getSystemClassLoader();
                }
                loader = systemClassLoader;
                if (loader == null) {
                    throw new ClassNotFoundException(v.getName());
                }
            }

            return Class.forName(v.getName(), false, loader);
        }
    }
}
