From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- xmlsecurity/source/helper/xsecsign.cxx | 447 +++++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 xmlsecurity/source/helper/xsecsign.cxx (limited to 'xmlsecurity/source/helper/xsecsign.cxx') diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx new file mode 100644 index 000000000..b9648ed64 --- /dev/null +++ b/xmlsecurity/source/helper/xsecsign.cxx @@ -0,0 +1,447 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + + +#include + +#include +#include +#include +#include + +#include +#include + +namespace com::sun::star::graphic { class XGraphic; } + +using namespace css; +using namespace css::uno; +using namespace css::graphic; + +/* protected: for signature generation */ +OUString XSecController::createId() +{ + sal_uInt8 aSeq[16]; + rtl_createUuid( aSeq, nullptr, true ); + + char str[68]="ID_"; + int length = 3; + for (sal_uInt8 i : aSeq) + { + length += sprintf(str+length, "%04x", i); + } + + return OUString::createFromAscii(str); +} + +css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite( + InternalSignatureInformation& internalSignatureInfor, + sal_Int32 nStorageFormat, + bool bXAdESCompliantIfODF) +{ + sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId; + SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors; + + sal_Int32 nIdOfSignatureElementCollector; + + nIdOfSignatureElementCollector = + m_xSAXEventKeeper->addSecurityElementCollector( css::xml::crypto::sax::ElementMarkPriority_AFTERMODIFY, true ); + + m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId); + + rtl::Reference xSignatureCreator(new SignatureCreatorImpl); + + css::uno::Sequence args(5); + args[0] <<= OUString::number(nSecurityId); + args[1] <<= uno::Reference(static_cast(m_xSAXEventKeeper.get()), uno::UNO_QUERY); + args[2] <<= OUString::number(nIdOfSignatureElementCollector); + + //for nss, the internal module is used for signing, which needs to be improved later + args[3] <<= m_xSecurityContext->getSecurityEnvironment(); + + args[4] <<= m_xXMLSignature; + xSignatureCreator->initialize(args); + + sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker(); + m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId); + + xSignatureCreator->setBlockerId(nBlockerId); + + xSignatureCreator->addSignatureCreationResultListener(this); + + m_xSAXEventKeeper->addReferenceResolvedListener(nIdOfSignatureElementCollector, xSignatureCreator.get()); + + int size = vReferenceInfors.size(); + sal_Int32 nReferenceCount = 0; + + for(int i=0; isetSecurityId(keeperId, nSecurityId); + m_xSAXEventKeeper->addReferenceResolvedListener( keeperId, xSignatureCreator.get()); + xSignatureCreator->setReferenceId( keeperId ); + nReferenceCount++; + } + } + + xSignatureCreator->setReferenceCount( nReferenceCount ); + + /* + * adds all URI binding + */ + for(int i=0; i xInputStream + = getObjectInputStream( refInfor.ouURI ); + + if (xInputStream.is()) + xSignatureCreator->setUriBinding(refInfor.ouURI,xInputStream); + } + + xSignatureCreator->setKeyId(0); + + // use sha512 for gpg signing unconditionally + const sal_Int32 digestID = !internalSignatureInfor.signatureInfor.ouGpgCertificate.isEmpty()? + css::xml::crypto::DigestID::SHA512 : (bXAdESCompliantIfODF ? css::xml::crypto::DigestID::SHA256 : css::xml::crypto::DigestID::SHA1); + + if (nStorageFormat != embed::StorageFormats::OFOPXML) + { + internalSignatureInfor.signatureInfor.ouSignatureId = createId(); + internalSignatureInfor.signatureInfor.ouPropertyId = createId(); + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouPropertyId, -1, OUString() ); + size++; + + if (bXAdESCompliantIfODF) + { + // We write a new reference, so it's possible to use the correct type URI. + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties", -1, "http://uri.etsi.org/01903#SignedProperties"); + size++; + } + + if (!internalSignatureInfor.signatureInfor.ouDescription.isEmpty()) + { + // Only mention the hash of the description in the signature if it's non-empty. + internalSignatureInfor.signatureInfor.ouDescriptionPropertyId = createId(); + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouDescriptionPropertyId, -1, OUString()); + size++; + } + } + else + { + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idPackageObject", -1, OUString()); + size++; + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idOfficeObject", -1, OUString()); + size++; + internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties", -1, OUString()); + size++; + } + + /* + * replace both digestValues and signatureValue to " " + */ + for(int i=0; i& xValidGraphic) +{ + int nIndex = findSignatureInfor(nSecurityId); + + if (nIndex == -1) + { + InternalSignatureInformation aInformation(nSecurityId, nullptr); + aInformation.signatureInfor.aValidSignatureImage = xValidGraphic; + m_vInternalSignatureInformations.push_back(aInformation); + } + else + { + SignatureInformation& rInformation + = m_vInternalSignatureInformations[nIndex].signatureInfor; + rInformation.aValidSignatureImage = xValidGraphic; + } +} + +void XSecController::setSignatureLineInvalidGraphic( + sal_Int32 nSecurityId, const Reference& xInvalidGraphic) +{ + int nIndex = findSignatureInfor(nSecurityId); + + if (nIndex == -1) + { + InternalSignatureInformation aInformation(nSecurityId, nullptr); + aInformation.signatureInfor.aInvalidSignatureImage = xInvalidGraphic; + m_vInternalSignatureInformations.push_back(aInformation); + } + else + { + SignatureInformation& rInformation + = m_vInternalSignatureInformations[nIndex].signatureInfor; + rInformation.aInvalidSignatureImage = xInvalidGraphic; + } +} + +bool XSecController::WriteSignature( + const css::uno::Reference& xDocumentHandler, + bool bXAdESCompliantIfODF ) +{ + bool rc = false; + + SAL_WARN_IF( !xDocumentHandler.is(), "xmlsecurity.helper", "I really need a document handler!" ); + + /* + * chain the SAXEventKeeper to the SAX chain + */ + chainOn(); + + if ( m_eStatusOfSecurityComponents == InitializationState::INITIALIZED ) + /* + * if all security components are ready, add the signature + * stream. + */ + { + m_bIsSAXEventKeeperSticky = true; + m_xSAXEventKeeper->setNextHandler(xDocumentHandler); + + try + { + /* + * export the signature template + */ + css::uno::Reference xSEKHandler(static_cast(m_xSAXEventKeeper.get()),css::uno::UNO_QUERY); + + int i; + int sigNum = m_vInternalSignatureInformations.size(); + + for (i=0; isetNextHandler( nullptr ); + m_bIsSAXEventKeeperSticky = false; + } + + return rc; +} + +bool XSecController::WriteOOXMLSignature(const uno::Reference& xRootStorage, const uno::Reference& xDocumentHandler) +{ + bool bRet = false; + + SAL_WARN_IF(!xDocumentHandler.is(), "xmlsecurity.helper", "empty xDocumentHandler reference"); + + // Chain the SAXEventKeeper to the SAX chain. + chainOn(); + + if (m_eStatusOfSecurityComponents == InitializationState::INITIALIZED) + { + m_bIsSAXEventKeeperSticky = true; + m_xSAXEventKeeper->setNextHandler(xDocumentHandler); + + try + { + // Export the signature template. + css::uno::Reference xSEKHandler(static_cast(m_xSAXEventKeeper.get()), uno::UNO_QUERY); + + for (InternalSignatureInformation & rInformation : m_vInternalSignatureInformations) + { + // Prepare the signature creator. + rInformation.xReferenceResolvedListener = prepareSignatureToWrite(rInformation, embed::StorageFormats::OFOPXML, false); + + exportOOXMLSignature(xRootStorage, xSEKHandler, rInformation.signatureInfor); + } + + m_bIsSAXEventKeeperSticky = false; + chainOff(); + + bRet = true; + } + catch(const uno::Exception&) + { + } + + m_xSAXEventKeeper->setNextHandler(nullptr); + m_bIsSAXEventKeeperSticky = false; + } + + return bRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3