/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#ifndef OOX_CORE_BINARYCODEC_HXX
#define OOX_CORE_BINARYCODEC_HXX

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/beans/NamedValue.hpp>

#include <rtl/cipher.h>
#include <rtl/digest.h>

namespace oox { class AttributeList; }

namespace oox {
namespace core {

// ============================================================================

class CodecHelper
{
public:
    /** Returns the password hash if it is in the required 16-bit limit. */
    static sal_uInt16   getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement );

private:
                        CodecHelper();
                        ~CodecHelper();
};

// ============================================================================

/** Encodes and decodes data from/to protected MS Office documents.

    Implements a simple XOR encoding/decoding algorithm used in MS Office
    versions up to MSO 95.
 */
class BinaryCodec_XOR
{
public:
    /** Enumerates codec types supported by this XOR codec implementation. */
    enum CodecType
    {
        CODEC_WORD,     /// MS Word XOR codec.
        CODEC_EXCEL     /// MS Excel XOR codec.
    };

public:
    /** Default constructor.

        Two-step construction in conjunction with the initKey() and verifyKey()
        functions allows to try to initialize with different passwords (e.g.
        built-in default password used for Excel workbook protection).
     */
    explicit            BinaryCodec_XOR( CodecType eCodecType );

                        ~BinaryCodec_XOR();

    /** Initializes the algorithm with the specified password.

        @param pnPassData
            Character array containing the password. Must be zero terminated,
            which results in a maximum length of 15 characters.
     */
    void                initKey( const sal_uInt8 pnPassData[ 16 ] );

    /** Initializes the algorithm with the encryption data.

        @param aData
            The sequence contains the necessary data to initialize
            the codec.
     */
    bool                initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );

    /** Retrieves the encryption data

        @return
            The sequence contains the necessary data to initialize
            the codec.
     */
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();

    /** Verifies the validity of the password using the passed key and hash.

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param nKey
            Password key value read from the file.
        @param nHash
            Password hash value read from the file.

        @return
            True = test was successful.
     */
    bool                verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;

    /** Reinitializes the codec to start a new memory block.

        Resets the internal key offset to 0.

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.
     */
    void                startBlock();

    /** Decodes a block of memory.

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param pnDestData
            Destination buffer. Will contain the decrypted data afterwards.
        @param pnSrcData
            Encrypted data block.
        @param nBytes
            Size of the passed data blocks. pnDestData and pnSrcData must be of
            this size.

        @return
            True = decoding was successful (no error occured).
    */
    bool                decode(
                            sal_uInt8* pnDestData,
                            const sal_uInt8* pnSrcData,
                            sal_Int32 nBytes );

    /** Lets the cipher skip a specific amount of bytes.

        This function sets the cipher to the same state as if the specified
        amount of data has been decoded with one or more calls of decode().

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param nBytes
            Number of bytes to be skipped (cipher "seeks" forward).

        @return
            True = skip was successful (no error occured).
     */
    bool                skip( sal_Int32 nBytes );

private:
    CodecType           meCodecType;        /// Codec type.
    sal_uInt8           mpnKey[ 16 ];       /// Encryption key.
    sal_Int32           mnOffset;           /// Key offset.
    sal_uInt16          mnBaseKey;          /// Base key from password.
    sal_uInt16          mnHash;             /// Hash value from password.
};

// ============================================================================

/** Encodes and decodes data from protected MSO 97+ documents.

    This is a wrapper class around low level cryptographic functions from RTL.
    Implementation is based on the wvDecrypt package by Caolan McNamara:
    http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
 */
class BinaryCodec_RCF
{
public:
    /** Default constructor.

        Two-step construction in conjunction with the initKey() and verifyKey()
        functions allows to try to initialize with different passwords (e.g.
        built-in default password used for Excel workbook protection).
     */
    explicit            BinaryCodec_RCF();

                        ~BinaryCodec_RCF();

    /** Initializes the algorithm with the encryption data.

        @param aData
            The sequence contains the necessary data to initialize
            the codec.
     */
    bool            initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );

    /** Retrieves the encryption data

        @return
            The sequence contains the necessary data to initialize
            the codec.
     */
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();

    /** Initializes the algorithm with the specified password and document ID.

        @param pnPassData
            Unicode character array containing the password. Must be zero
            terminated, which results in a maximum length of 15 characters.
        @param pnSalt
            Random salt data block read from or written to the file.
     */
    void                initKey(
                            const sal_uInt16 pnPassData[ 16 ],
                            const sal_uInt8 pnSalt[ 16 ] );

    /** Verifies the validity of the password using the passed salt data.

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param pnVerifier
            Verifier block read from the file.
        @param pnVerifierHash
            Verifier hash read from the file.

        @return
            True = test was successful.
     */
    bool                verifyKey(
                            const sal_uInt8 pnVerifier[ 16 ],
                            const sal_uInt8 pnVerifierHash[ 16 ] );

    /** Rekeys the codec using the specified counter.

        After reading a specific amount of data the cipher algorithm needs to
        be rekeyed using a counter that counts the data blocks.

        The block size is for example 512 bytes for MS Word files and 1024
        bytes for MS Excel files.

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param nCounter
            Block counter used to rekey the cipher.
     */
    bool                startBlock( sal_Int32 nCounter );

    /** Decodes a block of memory.

        @see rtl_cipher_decode()

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param pnDestData
            Destination buffer. Will contain the decrypted data afterwards.
        @param pnSrcData
            Encrypted data block.
        @param nBytes
            Size of the passed data blocks. pnDestData and pnSrcData must be of
            this size.

        @return
            True = decoding was successful (no error occured).
    */
    bool                decode(
                            sal_uInt8* pnDestData,
                            const sal_uInt8* pnSrcData,
                            sal_Int32 nBytes );

    /** Lets the cipher skip a specific amount of bytes.

        This function sets the cipher to the same state as if the specified
        amount of data has been decoded with one or more calls of decode().

        @precond
            The codec must be initialized with the initKey() function before
            this function can be used.

        @param nBytes
            Number of bytes to be skipped (cipher "seeks" forward).

        @return
            True = skip was successful (no error occured).
     */
    bool                skip( sal_Int32 nBytes );

private:
    void                InitKeyImpl(
                            const sal_uInt8 pKeyData[64],
                            const sal_uInt8 pUnique[16] );

    rtlCipher           mhCipher;
    rtlDigest           mhDigest;
    sal_uInt8           mpnDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
    sal_uInt8           mpnUnique[16];
};

// ============================================================================

} // namespace core
} // namespace oox

#endif
