/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: xsecsign.cxx,v $ * $Revision: 1.12 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmlsecurity.hxx" #include #include #include #include #include #include #include #include #include #include #include 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 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)); //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 xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY); xBlockerMonitor->setBlockerId(nBlockerId); cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster > xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY); xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this ); cssu::Reference xReferenceResolvedBroadcaster (m_xSAXEventKeeper, cssu::UNO_QUERY); xReferenceResolvedBroadcaster->addReferenceResolvedListener( nIdOfSignatureElementCollector, xReferenceResolvedListener); cssu::Reference xReferenceCollector (xReferenceResolvedListener, cssu::UNO_QUERY); int i; int size = vReferenceInfors.size(); sal_Int32 nReferenceCount = 0; for(i=0; isetSecurityId(keeperId, nSecurityId); xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener); xReferenceCollector->setReferenceId( keeperId ); nReferenceCount++; } } xReferenceCollector->setReferenceCount( nReferenceCount ); /* * adds all URI binding */ cssu::Reference xUriBinding (xReferenceResolvedListener, cssu::UNO_QUERY); for(i=0; i xInputStream = getObjectInputStream( refInfor.ouURI ); if (xInputStream.is()) { xUriBinding->setUriBinding(refInfor.ouURI,xInputStream); } } cssu::Reference 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; iaddSecurityElementCollector( 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& 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 xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY); int i; int sigNum = m_vInternalSignatureInformations.size(); for (i=0; isetNextHandler( NULL ); m_bIsSAXEventKeeperSticky = false; } else { m_pErrorMessage = ERROR_CANNOTCREATEXMLSECURITYCOMPONENT; } return rc; }