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