blob: 7e556a1880400e303388e3741e8e120d027bb2c6 [file] [log] [blame]
/**************************************************************
*
* 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;
}