| /************************************************************** |
| * |
| * 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 <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/XBlockerMonitor.hpp> |
| #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp> |
| #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp> |
| #include <com/sun/star/io/XActiveDataSource.hpp> |
| #include <rtl/uuid.h> |
| |
| #include <stdio.h> |
| |
| 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 SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator" |
| |
| /* protected: for signature generation */ |
| rtl::OUString XSecController::createId() |
| { |
| cssu::Sequence< sal_Int8 > aSeq( 16 ); |
| rtl_createUuid ((sal_uInt8 *)aSeq.getArray(), 0, sal_True); |
| |
| char str[68]="ID_"; |
| int length = 3; |
| for (int i=0; i<16; ++i) |
| { |
| length += sprintf(str+length, "%04x", (unsigned char)aSeq[i]); |
| } |
| |
| return rtl::OUString::createFromAscii(str); |
| } |
| |
| cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite( |
| InternalSignatureInformation& internalSignatureInfor ) |
| { |
| sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId; |
| SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors; |
| |
| sal_Int32 nIdOfSignatureElementCollector; |
| cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener; |
| |
| nIdOfSignatureElementCollector = |
| m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_True ); |
| |
| m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId); |
| |
| /* |
| * create a SignatureCreator |
| */ |
| cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); |
| xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >( |
| xMCF->createInstanceWithContext( |
| rtl::OUString::createFromAscii(SIGNATURECREATOR_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)); |
| |
| //i39448 : for nss, the internal module is used for signing, which needs to be improved later |
| sal_Int32 nEnvIndex = internalSignatureInfor.signatureInfor.nSecurityEnvironmentIndex; |
| if( nEnvIndex < 0 || nEnvIndex >= m_xSecurityContext->getSecurityEnvironmentNumber()) |
| {// set defaultEnv |
| args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironment()); |
| } |
| else |
| { |
| args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironmentByIndex(nEnvIndex)); |
| } |
| |
| args[4] = cssu::makeAny(m_xXMLSignature); |
| xInitialization->initialize(args); |
| |
| sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker(); |
| m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId); |
| |
| cssu::Reference<cssxc::sax::XBlockerMonitor> xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY); |
| xBlockerMonitor->setBlockerId(nBlockerId); |
| |
| cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster > |
| xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY); |
| |
| xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this ); |
| |
| cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> |
| xReferenceResolvedBroadcaster |
| (m_xSAXEventKeeper, |
| cssu::UNO_QUERY); |
| |
| xReferenceResolvedBroadcaster->addReferenceResolvedListener( |
| nIdOfSignatureElementCollector, |
| xReferenceResolvedListener); |
| |
| cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector |
| (xReferenceResolvedListener, cssu::UNO_QUERY); |
| |
| int i; |
| int size = vReferenceInfors.size(); |
| sal_Int32 nReferenceCount = 0; |
| |
| for(i=0; i<size; ++i) |
| { |
| sal_Int32 keeperId = internalSignatureInfor.vKeeperIds[i]; |
| |
| if ( keeperId != -1) |
| { |
| m_xSAXEventKeeper->setSecurityId(keeperId, nSecurityId); |
| xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener); |
| xReferenceCollector->setReferenceId( keeperId ); |
| nReferenceCount++; |
| } |
| } |
| |
| xReferenceCollector->setReferenceCount( nReferenceCount ); |
| |
| /* |
| * adds all URI binding |
| */ |
| cssu::Reference<cssxc::XUriBinding> xUriBinding |
| (xReferenceResolvedListener, cssu::UNO_QUERY); |
| |
| for(i=0; i<size; ++i) |
| { |
| const SignatureReferenceInformation& refInfor = vReferenceInfors[i]; |
| |
| cssu::Reference< com::sun::star::io::XInputStream > xInputStream |
| = getObjectInputStream( refInfor.ouURI ); |
| |
| if (xInputStream.is()) |
| { |
| xUriBinding->setUriBinding(refInfor.ouURI,xInputStream); |
| } |
| } |
| |
| cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY); |
| keyCollector->setKeyId(0); |
| |
| internalSignatureInfor.signatureInfor.ouSignatureId = createId(); |
| internalSignatureInfor.signatureInfor.ouPropertyId = createId(); |
| internalSignatureInfor.addReference(TYPE_SAMEDOCUMENT_REFERENCE, internalSignatureInfor.signatureInfor.ouPropertyId, -1 ); |
| size++; |
| |
| /* |
| * replace both digestValues and signatueValue to " " |
| */ |
| for(i=0; i<size; ++i) |
| { |
| SignatureReferenceInformation& refInfor = vReferenceInfors[i]; |
| refInfor.ouDigestValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK)); |
| } |
| |
| internalSignatureInfor.signatureInfor.ouSignatureValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK)); |
| |
| return xReferenceResolvedListener; |
| } |
| |
| /* public: for signature generation */ |
| void XSecController::collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId ) |
| { |
| /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */ |
| |
| chainOn(true); |
| |
| if ( m_nStatusOfSecurityComponents == INITIALIZED ) |
| /* |
| * if all security components are ready, add a signature. |
| */ |
| { |
| sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector( |
| cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_False); |
| |
| int index = findSignatureInfor( securityId ); |
| |
| if ( index == -1 ) |
| { |
| InternalSignatureInformation isi(securityId, NULL); |
| isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId ); |
| m_vInternalSignatureInformations.push_back( isi ); |
| } |
| else |
| { |
| m_vInternalSignatureInformations[index].addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId ); |
| } |
| } |
| } |
| |
| void XSecController::signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& /*objectURL*/, sal_Bool isBinary) |
| { |
| sal_Int32 type = ((isBinary==sal_True)?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE); |
| |
| int index = findSignatureInfor( securityId ); |
| |
| if (index == -1) |
| { |
| InternalSignatureInformation isi(securityId, NULL); |
| isi.addReference(type, uri, -1); |
| m_vInternalSignatureInformations.push_back( isi ); |
| } |
| else |
| { |
| m_vInternalSignatureInformations[index].addReference(type, uri, -1); |
| } |
| } |
| |
| void XSecController::setX509Certificate( |
| sal_Int32 nSecurityId, |
| const rtl::OUString& ouX509IssuerName, |
| const rtl::OUString& ouX509SerialNumber, |
| const rtl::OUString& ouX509Cert) |
| { |
| setX509Certificate(nSecurityId, -1, ouX509IssuerName, ouX509SerialNumber, ouX509Cert); |
| } |
| |
| void XSecController::setX509Certificate( |
| sal_Int32 nSecurityId, |
| const sal_Int32 nSecurityEnvironmentIndex, |
| const rtl::OUString& ouX509IssuerName, |
| const rtl::OUString& ouX509SerialNumber, |
| const rtl::OUString& ouX509Cert) |
| { |
| int index = findSignatureInfor( nSecurityId ); |
| |
| if ( index == -1 ) |
| { |
| InternalSignatureInformation isi(nSecurityId, NULL); |
| isi.signatureInfor.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex; |
| isi.signatureInfor.ouX509IssuerName = ouX509IssuerName; |
| isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber; |
| isi.signatureInfor.ouX509Certificate = ouX509Cert; |
| m_vInternalSignatureInformations.push_back( isi ); |
| } |
| else |
| { |
| SignatureInformation &si |
| = m_vInternalSignatureInformations[index].signatureInfor; |
| si.ouX509IssuerName = ouX509IssuerName; |
| si.ouX509SerialNumber = ouX509SerialNumber; |
| si.ouX509Certificate = ouX509Cert; |
| si.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex; |
| } |
| } |
| |
| void XSecController::setDate( |
| sal_Int32 nSecurityId, |
| const ::com::sun::star::util::DateTime& rDateTime ) |
| { |
| int index = findSignatureInfor( nSecurityId ); |
| |
| if ( index == -1 ) |
| { |
| InternalSignatureInformation isi(nSecurityId, NULL); |
| isi.signatureInfor.stDateTime = rDateTime; |
| m_vInternalSignatureInformations.push_back( isi ); |
| } |
| else |
| { |
| SignatureInformation &si |
| = m_vInternalSignatureInformations[index].signatureInfor; |
| si.stDateTime = rDateTime; |
| } |
| } |
| |
| bool XSecController::WriteSignature( |
| const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler ) |
| { |
| bool rc = false; |
| |
| DBG_ASSERT( xDocumentHandler.is(), "I really need a document handler!" ); |
| |
| /* |
| * chain the SAXEventKeeper to the SAX chain |
| */ |
| chainOn(true); |
| |
| if ( m_nStatusOfSecurityComponents == INITIALIZED ) |
| /* |
| * if all security components are ready, add the signature |
| * stream. |
| */ |
| { |
| m_bIsSAXEventKeeperSticky = true; |
| m_xSAXEventKeeper->setNextHandler(xDocumentHandler); |
| |
| try |
| { |
| /* |
| * export the signature template |
| */ |
| cssu::Reference<cssxs::XDocumentHandler> xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY); |
| |
| int i; |
| int sigNum = m_vInternalSignatureInformations.size(); |
| |
| for (i=0; i<sigNum; ++i) |
| { |
| InternalSignatureInformation &isi = m_vInternalSignatureInformations[i]; |
| |
| /* |
| * prepare the signature creator |
| */ |
| isi.xReferenceResolvedListener |
| = prepareSignatureToWrite( isi ); |
| |
| exportSignature( xSEKHandler, isi.signatureInfor ); |
| } |
| |
| m_bIsSAXEventKeeperSticky = false; |
| chainOff(); |
| |
| rc = true; |
| } |
| catch( cssxs::SAXException& ) |
| { |
| m_pErrorMessage = ERROR_SAXEXCEPTIONDURINGCREATION; |
| } |
| catch( com::sun::star::io::IOException& ) |
| { |
| m_pErrorMessage = ERROR_IOEXCEPTIONDURINGCREATION; |
| } |
| catch( cssu::Exception& ) |
| { |
| m_pErrorMessage = ERROR_EXCEPTIONDURINGCREATION; |
| } |
| |
| m_xSAXEventKeeper->setNextHandler( NULL ); |
| m_bIsSAXEventKeeperSticky = false; |
| } |
| else |
| { |
| m_pErrorMessage = ERROR_CANNOTCREATEXMLSECURITYCOMPONENT; |
| } |
| |
| return rc; |
| } |
| |