/************************************************************** * * 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 #include "xsecparser.hxx" #include #include #include #include #include #include #include // FIXME: copied from main/sal/rtl/source/strimp.c static sal_Bool rtl_ImplIsWhitespace( sal_Unicode c ) { /* Space or Control character? */ if ( (c <= 32) && c ) return sal_True; /* Only in the General Punctuation area Space or Control characters are included? */ if ( (c < 0x2000) || (c > 0x206F) ) return sal_False; if ( ((c >= 0x2000) && (c <= 0x200B)) || /* All Spaces */ (c == 0x2028) || /* LINE SEPARATOR */ (c == 0x2029) ) /* PARAGRAPH SEPARATOR */ return sal_True; return sal_False; } 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 xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY); cssu::Sequence 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 xReferenceResolvedBroadcaster (m_xSAXEventKeeper, cssu::UNO_QUERY); xReferenceResolvedBroadcaster->addReferenceResolvedListener( nIdOfSignatureElementCollector, xReferenceResolvedListener); cssu::Reference 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 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 xReferenceCollector (isi.xReferenceResolvedListener, cssu::UNO_QUERY); xReferenceCollector->setReferenceCount( referenceCount ); } } void XSecController::setIfEmpty(rtl::OUString &variable, const rtl::OUString &value) { if (variable.getLength() == 0) { variable = value; } else if (variable != value) { throw cssu::RuntimeException(rtl::OUString::createFromAscii("Value already set. Tampering?"), *this); } } void XSecController::setX509IssuerName( rtl::OUString& ouX509IssuerName ) { InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; setIfEmpty(isi.signatureInfor.ouX509IssuerName, ouX509IssuerName); } void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber ) { InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; setIfEmpty(isi.signatureInfor.ouX509SerialNumber, ouX509SerialNumber); } void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate ) { InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; setIfEmpty(isi.signatureInfor.ouX509Certificate, ouX509Certificate); if (isi.signatureInfor.ouX509Certificate.getLength()) { // We allow to re-set the same certificate only. // Whitespace may change. const sal_Int32 l1 = isi.signatureInfor.ouX509Certificate.getLength(); const sal_Int32 l2 = ouX509Certificate.getLength(); const sal_Unicode *s1 = isi.signatureInfor.ouX509Certificate.getStr(); const sal_Unicode *s2 = ouX509Certificate.getStr(); sal_Int32 i1 = 0, i2 = 0; while ((i1 < l1) && (i2 < l2)) { const sal_Unicode &c1 = s1[i1]; const sal_Unicode &c2 = s2[i2]; if (rtl_ImplIsWhitespace(c1)) { ++i1; continue; } if (rtl_ImplIsWhitespace(c2)) { ++i2; continue; } if (c1 != c2) { throw cssu::RuntimeException(rtl::OUString::createFromAscii("Value already set. Tampering?"), *this); } ++i1; ++i2; } // We could still have whitespace at the end of both strings while ((i1 < l1) && rtl_ImplIsWhitespace(s1[l1])) { ++i1; } while ((i2 < l2) && rtl_ImplIsWhitespace(s2[l2])) { ++i2; } if ((i1 != l1) || (i2 != l2)) { throw cssu::RuntimeException(rtl::OUString::createFromAscii("Value already set. Tampering?"), *this); } } 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 ); setIfEmpty(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; isetNextHandler(NULL); } sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False ); cssu::Reference xReferenceResolvedBroadcaster (m_xSAXEventKeeper, cssu::UNO_QUERY ); cssu::Reference 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; }