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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmlsecurity.hxx"
#include <xmlsecurity/digitalsignaturesdialog.hxx>
#include <xmlsecurity/certificatechooser.hxx>
#include <xmlsecurity/certificateviewer.hxx>
#include <xmlsecurity/biginteger.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/security/NoPasswordException.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/security/CertificateValidity.hdl>
#include <com/sun/star/packages/WrongPasswordException.hpp>
#include <com/sun/star/security/SerialNumberAdapter.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
#include <com/sun/star/packages/manifest/XManifestReader.hpp>


#include <rtl/ustrbuf.hxx>
#include <rtl/uri.hxx>

#include <tools/date.hxx>
#include <tools/time.hxx>

#include "dialogs.hrc"
#include "digitalsignaturesdialog.hrc"
#include "helpids.hrc"
#include "resourcemanager.hxx"

#include <vcl/msgbox.hxx> // Until encrypted docs work...
#include <unotools/configitem.hxx>
#include <comphelper/componentcontext.hxx>

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )


/* HACK: disable some warnings for MS-C */
#ifdef _MSC_VER
#pragma warning (disable : 4355)	// 4355: this used in initializer-list
#endif

using namespace ::com::sun::star::security;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
namespace css = ::com::sun::star;
using ::rtl::OUString;

namespace 
{
    class SaveODFItem: public utl::ConfigItem
    {
        sal_Int16 m_nODF;
    public: 
	virtual void Commit();
	virtual void Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
        SaveODFItem();
        //See group ODF in Common.xcs
        bool isLessODF1_2()
        {
            return m_nODF < 3;
        }
    };

void SaveODFItem::Commit() {}
void SaveODFItem::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& ) {}

    SaveODFItem::SaveODFItem(): utl::ConfigItem(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
        "Office.Common/Save"))), m_nODF(0)
    {
        OUString sDef(RTL_CONSTASCII_USTRINGPARAM("ODF/DefaultVersion"));
        Sequence< css::uno::Any > aValues = GetProperties( Sequence<OUString>(&sDef,1) );
        if ( aValues.getLength() == 1)
        {
            sal_Int16 nTmp = 0;
            if ( aValues[0] >>= nTmp )
                m_nODF = nTmp;
            else
                throw uno::RuntimeException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM(
                        "[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!")), 0 );

        }
        else
            throw uno::RuntimeException(
                OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion")), 0);
    }
}

/* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
    We use the manifest to find out if a file is xml and if it is encrypted.
    The parameter is an encoded uri. However, the manifest contains paths. Therefore
    the path is encoded as uri, so they can be compared.
*/
bool DigitalSignaturesDialog::isXML(const rtl::OUString& rURI )
{
    OSL_ASSERT(mxStore.is());

    bool bIsXML = false;
    bool bPropsAvailable = false;
    const OUString sPropFullPath(RTL_CONSTASCII_USTRINGPARAM("FullPath"));
    const OUString sPropMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
    const OUString sPropDigest(RTL_CONSTASCII_USTRINGPARAM("Digest"));

    for (int i = 0; i < m_manifest.getLength(); i++)
    {
        Any digest;
        const Sequence< css::beans::PropertyValue >& entry = m_manifest[i];
        OUString sPath, sMediaType;
        bool bEncrypted = false;
        for (int j = 0; j < entry.getLength(); j++)
        {
            const css::beans::PropertyValue & prop = entry[j];

            if (prop.Name.equals( sPropFullPath ) )
                prop.Value >>= sPath;
            else if (prop.Name.equals( sPropMediaType ) )
                prop.Value >>= sMediaType;
            else if (prop.Name.equals( sPropDigest ) )
                bEncrypted = true;
        }
        if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
        {
            bIsXML = sMediaType.equals(OUSTR("text/xml")) && ! bEncrypted;
            bPropsAvailable = true;
            break;
        }
    }
    if (!bPropsAvailable)
    {
        //This would be the case for at least mimetype, META-INF/manifest.xml
        //META-INF/macrosignatures.xml.
        //Files can only be encrypted if they are in the manifest.xml.
        //That is, the current file cannot be encrypted, otherwise bPropsAvailable
        //would be true.
        OUString aXMLExt( RTL_CONSTASCII_USTRINGPARAM( "XML" ) );
        sal_Int32 nSep = rURI.lastIndexOf( '.' );
        if ( nSep != (-1) )
        {
            OUString aExt = rURI.copy( nSep+1 );
            if (aExt.equalsIgnoreAsciiCase(aXMLExt ))
                bIsXML = true;
        }
     }
    return bIsXML;
}

DigitalSignaturesDialog::DigitalSignaturesDialog( 
    Window* pParent, 
    uno::Reference< uno::XComponentContext >& rxCtx, DocumentSignatureMode eMode, 
    sal_Bool bReadOnly, const ::rtl::OUString& sODFVersion, bool bHasDocumentSignature)
	:ModalDialog		( pParent, XMLSEC_RES( RID_XMLSECDLG_DIGSIG ) )
	,mxCtx 				( rxCtx )
	,maSignatureHelper	( rxCtx )
	,meSignatureMode	( eMode )
	,maHintDocFT		( this, XMLSEC_RES( FT_HINT_DOC ) )
	,maHintBasicFT		( this, XMLSEC_RES( FT_HINT_BASIC ) )
	,maHintPackageFT	( this, XMLSEC_RES( FT_HINT_PACK ) )
	,maSignaturesLB		( this, XMLSEC_RES( LB_SIGNATURES ) )
	,maSigsValidImg		( this, XMLSEC_RES( IMG_STATE_VALID ) )
	,maSigsValidFI		( this, XMLSEC_RES( FI_STATE_VALID ) )
	,maSigsInvalidImg	( this, XMLSEC_RES( IMG_STATE_BROKEN ) )
    ,maSigsInvalidFI    ( this, XMLSEC_RES( FI_STATE_BROKEN ) )
    ,maSigsNotvalidatedImg( this, XMLSEC_RES( IMG_STATE_NOTVALIDATED ) )
    ,maSigsNotvalidatedFI ( this, XMLSEC_RES( FI_STATE_NOTVALIDATED ) )
    ,maSigsOldSignatureFI ( this, XMLSEC_RES( FI_STATE_OLDSIGNATURE) )
    ,maViewBtn          ( this, XMLSEC_RES( BTN_VIEWCERT ) )
	,maAddBtn			( this, XMLSEC_RES( BTN_ADDCERT ) )
	,maRemoveBtn		( this, XMLSEC_RES( BTN_REMOVECERT ) )
	,maBottomSepFL		( this, XMLSEC_RES( FL_BOTTOM_SEP ) )
	,maOKBtn			( this, XMLSEC_RES( BTN_OK ) )
	,maHelpBtn			( this, XMLSEC_RES( BTN_HELP ) )
    ,m_sODFVersion (sODFVersion)
    ,m_bHasDocumentSignature(bHasDocumentSignature)
    ,m_bWarningShowSignMacro(false)
{
    // --> PB #i48253 the tablistbox needs its own unique id
    maSignaturesLB.Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG );
    // <--
    Size aControlSize( maSignaturesLB.GetSizePixel() );
    aControlSize = maSignaturesLB.PixelToLogic( aControlSize, MapMode( MAP_APPFONT ) );
    const long nControlWidth = aControlSize.Width();
    static long nTabs[] = { 4, 0, 6*nControlWidth/100, 36*nControlWidth/100, 74*nControlWidth/100 };
	maSignaturesLB.SetTabs( &nTabs[ 0 ] );
	maSignaturesLB.InsertHeaderEntry( String( XMLSEC_RES( STR_HEADERBAR ) ) );

    maSigsNotvalidatedFI.SetText( String( XMLSEC_RES( STR_NO_INFO_TO_VERIFY ) ) );

    if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
    {
        // high contrast mode needs other images
        maSigsValidImg.SetImage( Image( XMLSEC_RES( IMG_STATE_VALID_HC ) ) );
        maSigsInvalidImg.SetImage( Image( XMLSEC_RES( IMG_STATE_BROKEN_HC ) ) );
        maSigsNotvalidatedImg.SetImage( Image( XMLSEC_RES( IMG_STATE_NOTVALIDATED_HC ) ) );
    }

    FreeResource();

	mbVerifySignatures = true;
	mbSignaturesChanged = false;

	maSignaturesLB.SetSelectHdl( LINK( this, DigitalSignaturesDialog, SignatureHighlightHdl ) );
	maSignaturesLB.SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog, SignatureSelectHdl ) );

	maViewBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, ViewButtonHdl ) );
	maViewBtn.Disable();

	maAddBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, AddButtonHdl ) );
	if ( bReadOnly  )
	    maAddBtn.Disable();

	maRemoveBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, RemoveButtonHdl ) );
	maRemoveBtn.Disable();

    maOKBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, OKButtonHdl) );

	switch( meSignatureMode )
	{
		case SignatureModeDocumentContent:	maHintDocFT.Show();		break;
		case SignatureModeMacros:		    maHintBasicFT.Show();	break;
		case SignatureModePackage:	        maHintPackageFT.Show();	break;
	}

	// adjust fixed text to images
	XmlSec::AlignAndFitImageAndControl( maSigsValidImg, maSigsValidFI, 5 );
	XmlSec::AlignAndFitImageAndControl( maSigsInvalidImg, maSigsInvalidFI, 5 );
    XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsNotvalidatedFI, 5 );
    XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsOldSignatureFI, 5 );
}

DigitalSignaturesDialog::~DigitalSignaturesDialog()
{
}

sal_Bool DigitalSignaturesDialog::Init()
{
    bool bInit = maSignatureHelper.Init();

    DBG_ASSERT( bInit, "Error initializing security context!" );

    if ( bInit )
    {
        maSignatureHelper.SetStartVerifySignatureHdl( LINK( this, DigitalSignaturesDialog, StartVerifySignatureHdl ) );
    }

    return bInit;
}

void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStore )
{
    mxStore = rxStore;
    maSignatureHelper.SetStorage( mxStore, m_sODFVersion);
    
    Reference < css::packages::manifest::XManifestReader > xReader(
        mxCtx->getServiceManager()->createInstanceWithContext(
        OUSTR("com.sun.star.packages.manifest.ManifestReader"), mxCtx), UNO_QUERY_THROW);

	//Get the manifest.xml
    Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement( 
                OUSTR("META-INF"), css::embed::ElementModes::READ), UNO_QUERY_THROW);

    Reference< css::io::XInputStream > xStream(
        xSubStore->openStreamElement(OUSTR("manifest.xml"), css::embed::ElementModes::READ), 
        UNO_QUERY_THROW);

    m_manifest = xReader->readManifestSequence(xStream);
}

void DigitalSignaturesDialog::SetSignatureStream( const cssu::Reference < css::io::XStream >& rxStream )
{
    mxSignatureStream = rxStream;
}

bool DigitalSignaturesDialog::canAddRemove()
{
    //m56
    bool ret = true;
    OSL_ASSERT(mxStore.is());
    bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
    SaveODFItem item;
    bool bSave1_1 = item.isLessODF1_2();
    
    // see specification
    //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
    //Paragraph 'Behavior with regard to ODF 1.2'
    //For both, macro and document
    if ( (!bSave1_1  && bDoc1_1) || (bSave1_1 && bDoc1_1) )
    {
        //#4
        ErrorBox err(NULL, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT));
        err.Execute();
        ret = false;
    } 

    //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is 
    //adding a macro signature will break an existing document signature.
    //The sfx2 will remove the documentsignature when the user adds a macro signature
    if (meSignatureMode == SignatureModeMacros
        && ret)
    {
        if (m_bHasDocumentSignature && !m_bWarningShowSignMacro)
        {
            //The warning says that the document signatures will be removed if the user
            //continues. He can then either press 'OK' or 'NO' 
            //It the user presses 'Add' or 'Remove' several times then, then the warning
            //is shown every time until the user presses 'OK'. From then on, the warning
            //is not displayed anymore as long as the signatures dialog is alive.
            if (QueryBox(
                NULL, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)).Execute() == RET_NO)
                ret = false;
            else
                m_bWarningShowSignMacro = true;

        }
    }
    return ret;
} 

bool DigitalSignaturesDialog::canAdd()
{
    if (canAddRemove())
        return true;
    return false;
}

bool DigitalSignaturesDialog::canRemove()
{
    if (canAddRemove())
        return true;
    return false;
}

short DigitalSignaturesDialog::Execute()
{
    // Verify Signatures and add certificates to ListBox...
    mbVerifySignatures = true;
    ImplGetSignatureInformations(false);
    ImplFillSignaturesBox();

    // Only verify once, content will not change.
    // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
    mbVerifySignatures = false;

    return Dialog::Execute();
}

IMPL_LINK( DigitalSignaturesDialog, SignatureHighlightHdl, void*, EMPTYARG )
{
	bool bSel = maSignaturesLB.FirstSelected() ? true : false;
    maViewBtn.Enable( bSel );
    if ( maAddBtn.IsEnabled() ) // not read only
	    maRemoveBtn.Enable( bSel );

    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, OKButtonHdl, void*, EMPTYARG )
{
    // Export all other signatures...
    SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream( 
        embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false );
    uno::Reference< io::XOutputStream > xOutputStream( 
        aStreamHelper.xSignatureStream, uno::UNO_QUERY );
    uno::Reference< com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler = 
        maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );

    int nInfos = maCurrentSignatureInformations.size();
    for( int n = 0 ; n < nInfos ; ++n )
        maSignatureHelper.ExportSignature( 
        xDocumentHandler, maCurrentSignatureInformations[ n ] );

    maSignatureHelper.CloseDocumentHandler( xDocumentHandler);

    // If stream was not provided, we are responsible for committing it....
    if ( !mxSignatureStream.is() )
    {
        uno::Reference< embed::XTransactedObject > xTrans( 
            aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
        xTrans->commit();
    }  

    EndDialog(RET_OK);
    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, SignatureSelectHdl, void*, EMPTYARG )
{
    ImplShowSignaturesDetails();
    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, ViewButtonHdl, Button*, EMPTYARG )
{
    ImplShowSignaturesDetails();
    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, AddButtonHdl, Button*, EMPTYARG )
{
    if( ! canAdd())
        return 0;
    try
    {
        uno::Reference<com::sun::star::xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureHelper.GetSecurityEnvironment();

        uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter = 
			::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
        CertificateChooser aChooser( this, mxCtx, xSecEnv, maCurrentSignatureInformations );
        if ( aChooser.Execute() == RET_OK )
        {
            uno::Reference< ::com::sun::star::security::XCertificate > xCert = aChooser.GetSelectedCertificate();
            if ( !xCert.is() )
            {
                DBG_ERRORFILE( "no certificate selected" );
                return -1;
            }
            rtl::OUString aCertSerial = xSerialNumberAdapter->toString( xCert->getSerialNumber() );
            if ( !aCertSerial.getLength() )
            {
                DBG_ERROR( "Error in Certificate, problem with serial number!" );
                return -1;
            }

            maSignatureHelper.StartMission();

            sal_Int32 nSecurityId = maSignatureHelper.GetNewSecurityId();

            rtl::OUStringBuffer aStrBuffer;
            SvXMLUnitConverter::encodeBase64(aStrBuffer, xCert->getEncoded());
   
            maSignatureHelper.SetX509Certificate( nSecurityId,
                xCert->getIssuerName(), aCertSerial, 
                aStrBuffer.makeStringAndClear());

            std::vector< rtl::OUString > aElements = 
                DocumentSignatureHelper::CreateElementList( 
                    mxStore, rtl::OUString(), meSignatureMode, OOo3_2Document);

            sal_Int32 nElements = aElements.size();
            for ( sal_Int32 n = 0; n < nElements; n++ )
            {
                bool bBinaryMode = !isXML(aElements[n]);
                maSignatureHelper.AddForSigning( nSecurityId, aElements[n], aElements[n], bBinaryMode );
            }

            maSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );

            // We open a signature stream in which the existing and the new 
            //signature is written. ImplGetSignatureInformation (later in this function) will
            //then read the stream an will fill  maCurrentSignatureInformations. The final signature
            //is written when the user presses OK. Then only maCurrentSignatureInformation and 
            //a sax writer are used to write the information.
            SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
                css::embed::ElementModes::WRITE|css::embed::ElementModes::TRUNCATE, true);
            Reference< css::io::XOutputStream > xOutputStream( 
                aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
            Reference< css::xml::sax::XDocumentHandler> xDocumentHandler = 
                maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );

            // Export old signatures...
 	        int nInfos = maCurrentSignatureInformations.size();
            for ( int n = 0; n < nInfos; n++ )
	            maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[n]);

            // Create a new one...
	        maSignatureHelper.CreateAndWriteSignature( xDocumentHandler );

            // That's it...
	        maSignatureHelper.CloseDocumentHandler( xDocumentHandler);

            maSignatureHelper.EndMission();

			aStreamHelper = SignatureStreamHelper();	// release objects...
           
            mbSignaturesChanged = true;

            sal_Int32 nStatus = maSignatureHelper.GetSignatureInformation( nSecurityId ).nStatus;

            if ( nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
            {
                mbSignaturesChanged = true;

                // Can't simply remember current information, need parsing for getting full information :(
				// We need to verify the signatures again, otherwise the status in the signature information
				// will not contain
				// SecurityOperationStatus_OPERATION_SUCCEEDED
				mbVerifySignatures = true;
                ImplGetSignatureInformations(true);
                ImplFillSignaturesBox();
            }
        }
    }
	catch ( uno::Exception& )
	{
	    DBG_ERROR( "Exception while adding a signature!" );
		// Don't keep invalid entries...
		ImplGetSignatureInformations(true);
        ImplFillSignaturesBox();
	}

    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, RemoveButtonHdl, Button*, EMPTYARG )
{
    if (!canRemove())
        return 0;
	if( maSignaturesLB.FirstSelected() )
	{
	    try
	    {
            sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
    		maCurrentSignatureInformations.erase( maCurrentSignatureInformations.begin()+nSelected );

    		// Export all other signatures...
            SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
                css::embed::ElementModes::WRITE | css::embed::ElementModes::TRUNCATE, true);
            Reference< css::io::XOutputStream > xOutputStream( 
                aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
            Reference< css::xml::sax::XDocumentHandler> xDocumentHandler = 
                maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );

            int nInfos = maCurrentSignatureInformations.size();
    		for( int n = 0 ; n < nInfos ; ++n )
    			maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[ n ] );

    	    maSignatureHelper.CloseDocumentHandler( xDocumentHandler);

            mbSignaturesChanged = true;

			aStreamHelper = SignatureStreamHelper();	// release objects...

            ImplFillSignaturesBox();
        }
    	catch ( uno::Exception& )
    	{
    	    DBG_ERROR( "Exception while removing a signature!" );
			// Don't keep invalid entries...
			ImplGetSignatureInformations(true);
			ImplFillSignaturesBox();
    	}
	}

    return 0;
}

IMPL_LINK( DigitalSignaturesDialog, StartVerifySignatureHdl, void*, EMPTYARG )
{
    return mbVerifySignatures ? 1 : 0;
}

void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
    maSignaturesLB.Clear();

    uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = maSignatureHelper.GetSecurityEnvironment();
    uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter = 
        ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);

    uno::Reference< ::com::sun::star::security::XCertificate > xCert;

	String aNullStr;
	int nInfos = maCurrentSignatureInformations.size();
    int nValidSigs = 0, nValidCerts = 0;
    bool bAllNewSignatures = true;

    if( nInfos )
    {
        for( int n = 0; n < nInfos; ++n )
        {
            DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
                m_sODFVersion, maCurrentSignatureInformations[n]);
            std::vector< rtl::OUString > aElementsToBeVerified = 
                DocumentSignatureHelper::CreateElementList( 
                mxStore, ::rtl::OUString(), meSignatureMode, mode);

            const SignatureInformation& rInfo = maCurrentSignatureInformations[n];
			//First we try to get the certificate which is embedded in the XML Signature
            if (rInfo.ouX509Certificate.getLength())
			    xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
            else {
                //There must be an embedded certificate because we use it to get the
                //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
                //because it could be modified by an attacker. The issuer is displayed
                //in the digital signature dialog.
                //Comparing the X509IssuerName with the one from the X509Certificate in order
                //to find out if the X509IssuerName was modified does not work. See #i62684
                DBG_ASSERT(sal_False, "Could not find embedded certificate!");
            }
            
			//In case there is no embedded certificate we try to get it from a local store
            //Todo: This probably could be removed, see above.
			if (!xCert.is())
				xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );

		    DBG_ASSERT( xCert.is(), "Certificate not found and can't be created!" );

		    String	aSubject;
		    String	aIssuer;
		    String	aDateTimeStr;

            bool bSigValid = false;
            bool bCertValid = false;
            if( xCert.is() )
		    {
                //check the validity of the cert
                try {
                    sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
                        Sequence<css::uno::Reference<css::security::XCertificate> >());
                    
                    bCertValid = certResult == css::security::CertificateValidity::VALID ? true : false;
                    if ( bCertValid )
                        nValidCerts++;

                } catch (css::uno::SecurityException& ) {
                    OSL_ENSURE(0, "Verification of certificate failed");
                    bCertValid = false;
                }

                aSubject = XmlSec::GetContentPart( xCert->getSubjectName() );
                aIssuer = XmlSec::GetContentPart( xCert->getIssuerName() );
                // --> PB 2004-10-12 #i20172# String with date and time information
                aDateTimeStr = XmlSec::GetDateTimeString( rInfo.stDateTime );
            }
            bSigValid = ( rInfo.nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );

            if ( bSigValid )
            {
                 bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
                      aElementsToBeVerified, rInfo, mode);

                if( bSigValid )
			        nValidSigs++;
            }
            
            Image aImage;
            if (!bSigValid)
            {
                aImage = maSigsInvalidImg.GetImage();
            }
            else if (bSigValid && !bCertValid)
            {
                aImage = maSigsNotvalidatedImg.GetImage();
            }
            //Check if the signature is a "old" document signature, that is, which was created
            //by an version of OOo previous to 3.2
            else if (meSignatureMode == SignatureModeDocumentContent 
                && bSigValid && bCertValid && !DocumentSignatureHelper::isOOo3_2_Signature(
                maCurrentSignatureInformations[n]))
            {
                aImage = maSigsNotvalidatedImg.GetImage();
                bAllNewSignatures &= false;
            }
            else if (meSignatureMode == SignatureModeDocumentContent
                && bSigValid && bCertValid && DocumentSignatureHelper::isOOo3_2_Signature(
                maCurrentSignatureInformations[n]))
            {
                aImage = maSigsValidImg.GetImage();
            }
            else if (meSignatureMode == SignatureModeMacros
                && bSigValid && bCertValid)
            {
                aImage = aImage = maSigsValidImg.GetImage();
            }
            
            SvLBoxEntry* pEntry = maSignaturesLB.InsertEntry( aNullStr, aImage, aImage );
		    maSignaturesLB.SetEntryText( aSubject, pEntry, 1 );
		    maSignaturesLB.SetEntryText( aIssuer, pEntry, 2 );
		    maSignaturesLB.SetEntryText( aDateTimeStr, pEntry, 3 );
		    pEntry->SetUserData( ( void* ) n );		// missuse user data as index
        }
    }

    bool bAllSigsValid = (nValidSigs == nInfos);
    bool bAllCertsValid = (nValidCerts == nInfos);
    bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
    
    bool bShowNotValidatedState = nInfos && (bAllSigsValid && (!bAllCertsValid || !bAllNewSignatures));
    bool bShowInvalidState = nInfos && !bAllSigsValid;

	maSigsValidImg.Show( bShowValidState);
	maSigsValidFI.Show( bShowValidState );
	maSigsInvalidImg.Show( bShowInvalidState );
	maSigsInvalidFI.Show( bShowInvalidState );

    maSigsNotvalidatedImg.Show(bShowNotValidatedState);
    //bAllNewSignatures is always true if we are not in document mode
    maSigsNotvalidatedFI.Show(nInfos && bAllSigsValid && ! bAllCertsValid);
    maSigsOldSignatureFI.Show(nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures);

	SignatureHighlightHdl( NULL );
}


//If bUseTempStream is true then the temporary signature stream is used.
//Otherwise the real signature stream is used.
void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
{
    maCurrentSignatureInformations.clear();

    maSignatureHelper.StartMission();

    SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
        css::embed::ElementModes::READ, bUseTempStream);
    if ( aStreamHelper.xSignatureStream.is() )
    {
        uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
	    maSignatureHelper.ReadAndVerifySignature( xInputStream );
    }
    maSignatureHelper.EndMission();

    maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();

    mbVerifySignatures = false;
}

void DigitalSignaturesDialog::ImplShowSignaturesDetails()
{
	if( maSignaturesLB.FirstSelected() )
	{
        sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
		const SignatureInformation&	rInfo = maCurrentSignatureInformations[ nSelected ];
		css::uno::Reference<css::xml::crypto::XSecurityEnvironment > xSecEnv =
			maSignatureHelper.GetSecurityEnvironment();
        css::uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter = 
            ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
		// Use Certificate from doc, not from key store
		uno::Reference< dcss::security::XCertificate > xCert;
		if (rInfo.ouX509Certificate.getLength())
			xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
		//fallback if no certificate is embedded, get if from store
		if (!xCert.is())
			xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );

		DBG_ASSERT( xCert.is(), "Error getting cCertificate!" );
		if ( xCert.is() )
		{
			CertificateViewer aViewer( this, maSignatureHelper.GetSecurityEnvironment(), xCert, sal_False );
			aViewer.Execute();
		}
	}
}

//If bTempStream is true, then a temporary stream is return. If it is false then, the actual
//signature stream is used.
//Everytime the user presses Add a new temporary stream is created.
//We keep the temporary stream as member because ImplGetSignatureInformations
//will later access the stream to create DocumentSignatureInformation objects 
//which are stored in maCurrentSignatureInformations.
SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream(
    sal_Int32 nStreamOpenMode, bool bTempStream)
{
	SignatureStreamHelper aHelper;
    if (bTempStream)
    {
        if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
        {
            //We write always into a new temporary stream.
            mxTempSignatureStream = Reference < css::io::XStream >( 
                mxCtx->getServiceManager()->createInstanceWithContext(
                OUSTR( "com.sun.star.io.TempFile" ), mxCtx) ,
                UNO_QUERY_THROW);
            aHelper.xSignatureStream = mxTempSignatureStream;
        }
        else
        {
            //When we read from the temp stream, then we must have previously 
            //created one.
            OSL_ASSERT(mxTempSignatureStream.is());
        }
        aHelper.xSignatureStream = mxTempSignatureStream;
    }
    else
    {
        //No temporary stream
        if (!mxSignatureStream.is())
        {
            //We may not have a dedicated stream for writing the signature
            //So we take one directly from the storage
            //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
            //in which case Add/Remove is not allowed. This is done, for example, if the 
            //document is readonly
            aHelper = DocumentSignatureHelper::OpenSignatureStream(
                mxStore, nStreamOpenMode, meSignatureMode );
        }
        else
        {
            aHelper.xSignatureStream = mxSignatureStream;
        }
    }

    if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
    {
        css::uno::Reference < css::io::XTruncate > xTruncate( 
            aHelper.xSignatureStream, UNO_QUERY_THROW);
        DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
        xTruncate->truncate();
    }
    else if ( bTempStream || mxSignatureStream.is())
    {
        //In case we read the signature stream from the storage directly,
        //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
        //then XSeakable is not supported
        css::uno::Reference < css::io::XSeekable > xSeek(
            aHelper.xSignatureStream, UNO_QUERY_THROW);
        DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
        xSeek->seek( 0 );
    }

	return aHelper;
}

