/**************************************************************
 * 
 * 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 <xsecctl.hxx>
#include "xsecparser.hxx"
#include <tools/debug.hxx>

#include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
#include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
#include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxs = com::sun::star::xml::sax;

/* xml security framework components */
#define SIGNATUREVERIFIER_COMPONENT "com.sun.star.xml.crypto.sax.SignatureVerifier"

/* protected: for signature verify */
cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
	sal_Int32 nSecurityId)
{
	if ( m_nStatusOfSecurityComponents != INITIALIZED )
	{
		return NULL;
	}

	sal_Int32 nIdOfSignatureElementCollector;
	cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;

	nIdOfSignatureElementCollector = 
		m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False);

	m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);
        
        /*
         * create a SignatureVerifier
         */
	cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
	xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >(
		xMCF->createInstanceWithContext(
			rtl::OUString::createFromAscii( SIGNATUREVERIFIER_COMPONENT ), mxCtx),
		cssu::UNO_QUERY);
	
	cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);
	
	cssu::Sequence<cssu::Any> args(5);
	args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId));
	args[1] = cssu::makeAny(m_xSAXEventKeeper);
	args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector));
	args[3] = cssu::makeAny(m_xSecurityContext);
	args[4] = cssu::makeAny(m_xXMLSignature);
	xInitialization->initialize(args);
	
	cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
		signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);
		
	signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );

	cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster  
		(m_xSAXEventKeeper,
		cssu::UNO_QUERY);
		
	xReferenceResolvedBroadcaster->addReferenceResolvedListener(
		nIdOfSignatureElementCollector,
		xReferenceResolvedListener);
		
	cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
	keyCollector->setKeyId(0);
	
	return xReferenceResolvedListener;
}

void XSecController::addSignature()
{
	cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener = NULL;
	sal_Int32 nSignatureId = 0;
	
	
	if (m_bVerifyCurrentSignature)
	{
		chainOn(true);
		xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId );
		m_bVerifyCurrentSignature = false;
		nSignatureId = m_nReservedSignatureId;
	}
	
	InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener );
	m_vInternalSignatureInformations.push_back( isi );
}

void XSecController::addReference( const rtl::OUString& ouUri)
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE,ouUri, -1 );
}

void XSecController::addStreamReference( 
	const rtl::OUString& ouUri,
	bool isBinary )
{
        sal_Int32 type = (isBinary?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE);

	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];

	if ( isi.xReferenceResolvedListener.is() )
	{
	        /*
	         * get the input stream
	         */
        	cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream
        		= getObjectInputStream( ouUri );
		
		if ( xObjectInputStream.is() )
		{
			cssu::Reference<cssxc::XUriBinding> xUriBinding
				(isi.xReferenceResolvedListener, cssu::UNO_QUERY);
			xUriBinding->setUriBinding(ouUri, xObjectInputStream);
		}
	}
	
	isi.addReference(type, ouUri, -1);
}

void XSecController::setReferenceCount() const
{
	const InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	
	if ( isi.xReferenceResolvedListener.is() )
	{
		const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors;
		
		int refNum = refInfors.size();
		sal_Int32 referenceCount = 0;
			
		for(int i=0 ; i<refNum; ++i)
		{
			if (refInfors[i].nType == TYPE_SAMEDOCUMENT_REFERENCE )
			/*
			 * same-document reference
			 */
			{
				referenceCount++;
			}
		}
		
		cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
			(isi.xReferenceResolvedListener, cssu::UNO_QUERY);
		xReferenceCollector->setReferenceCount( referenceCount );
	}
}

void XSecController::setX509IssuerName( rtl::OUString& ouX509IssuerName )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
}

void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
}

void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouX509Certificate = ouX509Certificate;
}

void XSecController::setSignatureValue( rtl::OUString& ouSignatureValue )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouSignatureValue = ouSignatureValue;
}

void XSecController::setDigestValue( rtl::OUString& ouDigestValue )
{
	SignatureInformation &si = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1].signatureInfor;
	SignatureReferenceInformation &reference = si.vSignatureReferenceInfors[si.vSignatureReferenceInfors.size()-1];
	reference.ouDigestValue = ouDigestValue;
}

void XSecController::setDate( rtl::OUString& ouDate )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	convertDateTime( isi.signatureInfor.stDateTime, ouDate );
	isi.signatureInfor.ouDateTime = ouDate;
}

/*
void XSecController::setTime( rtl::OUString& ouTime )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouTime = ouTime;
}
*/

void XSecController::setId( rtl::OUString& ouId )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouSignatureId = ouId;
}

void XSecController::setPropertyId( rtl::OUString& ouPropertyId )
{
	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
	isi.signatureInfor.ouPropertyId = ouPropertyId;
}

/* public: for signature verify */
void XSecController::collectToVerify( const rtl::OUString& referenceId )
{
	/* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */
	
	if ( m_nStatusOfSecurityComponents == INITIALIZED )
	/*
	 * if all security components are ready, verify the signature.
	 */
	{
		bool bJustChainingOn = false;
		cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL;
		
		int i,j;
		int sigNum = m_vInternalSignatureInformations.size();
		
		for (i=0; i<sigNum; ++i)
		{
			InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
			SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
			int refNum = vReferenceInfors.size();
			
			for (j=0; j<refNum; ++j)
			{
				SignatureReferenceInformation &refInfor = vReferenceInfors[j];
				
				if (refInfor.ouURI == referenceId)
				{
					if (chainOn(false))
					{
						bJustChainingOn = true;
						xHandler = m_xSAXEventKeeper->setNextHandler(NULL);
					}
					
					sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
						cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False );
	
					cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster  
						(m_xSAXEventKeeper,
						cssu::UNO_QUERY );
						
					cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
						( isi.xReferenceResolvedListener, cssu::UNO_QUERY );
					
					m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
					xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
					xReferenceCollector->setReferenceId( nKeeperId );
					
					isi.vKeeperIds[j] = nKeeperId;
					break;
				}
			}
		}
	
		if ( bJustChainingOn )
		{
			cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
			if (m_xElementStackKeeper.is())
			{
				m_xElementStackKeeper->retrieve(xSEKHandler, sal_True);
			}
			m_xSAXEventKeeper->setNextHandler(xHandler);
		}
	}
}

void XSecController::addSignature( sal_Int32 nSignatureId )
{
	DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" );
	
	m_nReservedSignatureId = nSignatureId;
	m_bVerifyCurrentSignature = true;
}

cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader()
{
	m_pXSecParser = new XSecParser( this, NULL );
	cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser;
	
	setSAXChainConnector(xInitialization, NULL, NULL);
	
	return m_pXSecParser;
}
	
void XSecController::releaseSignatureReader()
{
	clearSAXChainConnector( );
	m_pXSecParser = NULL;
}

