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



#include <precompiled_xmlsecurity.hxx>

#include <osl/time.h>
#include <rtl/random.h>
#include <rtl/ref.hxx>

#include "ciphercontext.hxx"

using namespace ::com::sun::star;

uno::Reference< xml::crypto::XCipherContext > OCipherContext::Create( CK_MECHANISM_TYPE nNSSCipherID, const uno::Sequence< ::sal_Int8 >& aKey, const uno::Sequence< ::sal_Int8 >& aInitializationVector, bool bEncryption, bool bW3CPadding )
{
    ::rtl::Reference< OCipherContext > xResult = new OCipherContext;

    xResult->m_pSlot = PK11_GetBestSlot( nNSSCipherID, NULL );
    if ( xResult->m_pSlot )
    {
        SECItem aKeyItem = { siBuffer, const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aKey.getConstArray() ) ), static_cast<unsigned>(aKey.getLength()) };
        xResult->m_pSymKey = PK11_ImportSymKey( xResult->m_pSlot, nNSSCipherID, PK11_OriginDerive, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, &aKeyItem, NULL );
        if ( xResult->m_pSymKey )
        {
            SECItem aIVItem = { siBuffer, const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aInitializationVector.getConstArray() ) ), static_cast<unsigned>(aInitializationVector.getLength()) };
            xResult->m_pSecParam = PK11_ParamFromIV( nNSSCipherID, &aIVItem );
            if ( xResult->m_pSecParam )
            {
                xResult->m_pContext = PK11_CreateContextBySymKey( nNSSCipherID, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, xResult->m_pSymKey, xResult->m_pSecParam);
                if ( xResult->m_pContext )
                {
                    xResult->m_bEncryption = bEncryption;
                    xResult->m_bW3CPadding = bW3CPadding;
                    xResult->m_bPadding = bW3CPadding || ( PK11_GetPadMechanism( nNSSCipherID ) == nNSSCipherID );
                    xResult->m_nBlockSize = PK11_GetBlockSize( nNSSCipherID, xResult->m_pSecParam );
                    if ( xResult->m_nBlockSize <= SAL_MAX_INT8 )
                        return xResult.get();
                }
            }
        }
    }

    return uno::Reference< xml::crypto::XCipherContext >();
}

void OCipherContext::Dispose()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if ( m_pContext )
    {
        PK11_DestroyContext( m_pContext, PR_TRUE );
        m_pContext = NULL;
    }

    if ( m_pSecParam )
    {
        SECITEM_FreeItem( m_pSecParam, PR_TRUE );
        m_pSecParam = NULL;
    }

    if ( m_pSymKey )
    {
        PK11_FreeSymKey( m_pSymKey );
        m_pSymKey = NULL;
    }

    if ( m_pSlot )
    {
        PK11_FreeSlot( m_pSlot );
        m_pSlot = NULL;
    }

    m_bDisposed = true;
}

uno::Sequence< ::sal_Int8 > SAL_CALL OCipherContext::convertWithCipherContext( const uno::Sequence< ::sal_Int8 >& aData )
    throw ( lang::IllegalArgumentException, lang::DisposedException, uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if ( m_bBroken )
        throw uno::RuntimeException();

    if ( m_bDisposed )
        throw lang::DisposedException();

    uno::Sequence< sal_Int8 > aToConvert;
    if ( aData.getLength() )
    {
        sal_Int32 nOldLastBlockLen = m_aLastBlock.getLength();
        OSL_ENSURE( nOldLastBlockLen <= m_nBlockSize, "Unexpected last block size!" );

        sal_Int32 nAvailableData = nOldLastBlockLen + aData.getLength();
        sal_Int32 nToConvertLen = nAvailableData;
        if ( m_bEncryption || !m_bW3CPadding )
        {
            if ( nAvailableData % m_nBlockSize == 0 )
                nToConvertLen = nAvailableData;
            else if ( nAvailableData < m_nBlockSize )
                nToConvertLen = 0;
            else
                nToConvertLen = nAvailableData - nAvailableData % m_nBlockSize;
        }
        else
        {
            // decryption with W3C padding needs at least one block for finalizing
            if ( nAvailableData < m_nBlockSize * 2 )
                nToConvertLen = 0;
            else
                nToConvertLen = nAvailableData - nAvailableData % m_nBlockSize - m_nBlockSize;
        }

        aToConvert.realloc( nToConvertLen );
        if ( nToConvertLen == 0 )
        {
            m_aLastBlock.realloc( nOldLastBlockLen + aData.getLength() );
            rtl_copyMemory( m_aLastBlock.getArray() + nOldLastBlockLen, aData.getConstArray(), aData.getLength() );
            // aToConvert stays empty
        }
        else if ( nToConvertLen < nOldLastBlockLen )
        {
            rtl_copyMemory( aToConvert.getArray(), m_aLastBlock.getConstArray(), nToConvertLen );
            rtl_copyMemory( m_aLastBlock.getArray(), m_aLastBlock.getConstArray() + nToConvertLen, nOldLastBlockLen - nToConvertLen );
            m_aLastBlock.realloc( nOldLastBlockLen - nToConvertLen + aData.getLength() );
            rtl_copyMemory( m_aLastBlock.getArray() + nOldLastBlockLen - nToConvertLen, aData.getConstArray(), aData.getLength() );
        }
        else
        {
            rtl_copyMemory( aToConvert.getArray(), m_aLastBlock.getConstArray(), nOldLastBlockLen );
            if ( nToConvertLen > nOldLastBlockLen )
                rtl_copyMemory( aToConvert.getArray() + nOldLastBlockLen, aData.getConstArray(), nToConvertLen - nOldLastBlockLen );
            m_aLastBlock.realloc( nAvailableData - nToConvertLen );
            rtl_copyMemory( m_aLastBlock.getArray(), aData.getConstArray() + nToConvertLen - nOldLastBlockLen, nAvailableData - nToConvertLen );
        }
    }

    uno::Sequence< sal_Int8 > aResult;
    OSL_ENSURE( aToConvert.getLength() % m_nBlockSize == 0, "Unexpected size of the data to encrypt!" );
    if ( aToConvert.getLength() )
    {
        int nResultLen = 0;
        aResult.realloc( aToConvert.getLength() + m_nBlockSize );
        if ( PK11_CipherOp( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() ), &nResultLen, aResult.getLength(), const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aToConvert.getConstArray() ) ), aToConvert.getLength() ) != SECSuccess )
        {
            m_bBroken = true;
            Dispose();
            throw uno::RuntimeException();
        }

        m_nConverted += aToConvert.getLength();
        aResult.realloc( nResultLen );
    }

    return aResult;
}

uno::Sequence< ::sal_Int8 > SAL_CALL OCipherContext::finalizeCipherContextAndDispose()
    throw (lang::DisposedException, uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if ( m_bBroken )
        throw uno::RuntimeException();

    if ( m_bDisposed )
        throw lang::DisposedException();

    OSL_ENSURE( m_nBlockSize <= SAL_MAX_INT8, "Unexpected block size!" );
    OSL_ENSURE( m_nConverted % m_nBlockSize == 0, "Unexpected amount of bytes is already converted!" );
    sal_Int32 nSizeForPadding = ( m_nConverted + m_aLastBlock.getLength() ) % m_nBlockSize;

    // if it is decryption, the amount of data should be rounded to the block size even in case of padding
    if ( ( !m_bPadding || !m_bEncryption ) && nSizeForPadding )
        throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The data should contain complete blocks only." ) ), uno::Reference< uno::XInterface >() );

    if ( m_bW3CPadding && m_bEncryption )
    {
        // in this case the last block should be smaller than standard block
        // it will be increased with the padding
        OSL_ENSURE( m_aLastBlock.getLength() < m_nBlockSize, "Unexpected size of cashed incomplete last block!" );

        // W3CPadding handling for encryption
        sal_Int32 nPaddingSize = m_nBlockSize - nSizeForPadding;
        sal_Int32 nOldLastBlockLen = m_aLastBlock.getLength();
        m_aLastBlock.realloc( nOldLastBlockLen + nPaddingSize );

        if ( nPaddingSize > 1 )
        {
            TimeValue aTime;
            osl_getSystemTime( &aTime );
            rtlRandomPool aRandomPool = rtl_random_createPool();
            rtl_random_addBytes( aRandomPool, &aTime, 8 );
            rtl_random_getBytes( aRandomPool, m_aLastBlock.getArray() + nOldLastBlockLen, nPaddingSize - 1 );
            rtl_random_destroyPool ( aRandomPool );
        }
        m_aLastBlock[m_aLastBlock.getLength() - 1] = static_cast< sal_Int8 >( nPaddingSize );
    }

    // finally should the last block be smaller than two standard blocks
    OSL_ENSURE( m_aLastBlock.getLength() < m_nBlockSize * 2 , "Unexpected size of cashed incomplete last block!" );

    uno::Sequence< sal_Int8 > aResult;
    if ( m_aLastBlock.getLength() )
    {
        int nPrefResLen = 0;
        aResult.realloc( m_aLastBlock.getLength() + m_nBlockSize );
        if ( PK11_CipherOp( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() ), &nPrefResLen, aResult.getLength(), const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( m_aLastBlock.getConstArray() ) ), m_aLastBlock.getLength() ) != SECSuccess )
        {
            m_bBroken = true;
            Dispose();
            throw uno::RuntimeException();
        }

        aResult.realloc( nPrefResLen );
        m_aLastBlock.realloc( 0 );
    }

    sal_Int32 nPrefixLen = aResult.getLength();
    aResult.realloc( nPrefixLen + m_nBlockSize * 2 );
    unsigned nFinalLen = 0;
    if ( PK11_DigestFinal( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() + nPrefixLen ), &nFinalLen, aResult.getLength() - nPrefixLen ) != SECSuccess )
    {
        m_bBroken = true;
        Dispose();
        throw uno::RuntimeException();
    }

    aResult.realloc( nPrefixLen + nFinalLen );

    if ( m_bW3CPadding && !m_bEncryption )
    {
        // W3CPadding handling for decryption
        // aResult should have enough data, since we let m_aLastBlock be big enough in case of decryption
        OSL_ENSURE( aResult.getLength() >= m_nBlockSize, "Not enough data to handle the padding!" );

        sal_Int8 nBytesToRemove = aResult[aResult.getLength() - 1];
        if ( nBytesToRemove <= 0 || nBytesToRemove > aResult.getLength() )
        {
            m_bBroken = true;
            Dispose();
            throw uno::RuntimeException();
        }

        aResult.realloc( aResult.getLength() - nBytesToRemove );
    }

    Dispose();

    return aResult;
}
