diff options
Diffstat (limited to 'xmlsecurity/source/helper/xsecsign.cxx')
-rw-r--r-- | xmlsecurity/source/helper/xsecsign.cxx | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx new file mode 100644 index 000000000000..d64f1adc1623 --- /dev/null +++ b/xmlsecurity/source/helper/xsecsign.cxx @@ -0,0 +1,376 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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(RTL_CONSTASCII_USTRINGPARAM(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; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |