tdf#83877 Write SignatureLineId to ODF & OOXML signatures

Change-Id: I483a3b7895cdcb10ef9d6dacf167ed0f8db7e723
Reviewed-on: https://gerrit.libreoffice.org/54432
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
This commit is contained in:
Samuel Mehrbrodt
2018-05-16 16:34:35 +02:00
parent 168034416c
commit 201321f648
17 changed files with 97 additions and 22 deletions

View File

@@ -145,7 +145,7 @@ void SignSignatureLineDialog::Apply()
} }
SfxObjectShell* pShell = SfxObjectShell::Current(); SfxObjectShell* pShell = SfxObjectShell::Current();
pShell->SignDocumentContent(m_xSelectedCertifate); pShell->SignDocumentContent(m_xSelectedCertifate, m_aSignatureLineId);
bool bSuccess = false; // TODO bool bSuccess = false; // TODO

View File

@@ -265,6 +265,7 @@ public:
SAL_DLLPRIVATE bool SAL_DLLPRIVATE bool
SignContents_Impl(const css::uno::Reference<css::security::XCertificate> xCert, SignContents_Impl(const css::uno::Reference<css::security::XCertificate> xCert,
const OUString& aSignatureLineId,
bool bScriptingContent, const OUString& aODFVersion, bool bScriptingContent, const OUString& aODFVersion,
bool bHasValidDocumentSignature); bool bHasValidDocumentSignature);

View File

@@ -356,7 +356,8 @@ public:
// xmlsec05, check with SFX team // xmlsec05, check with SFX team
SignatureState GetDocumentSignatureState(); SignatureState GetDocumentSignatureState();
void SignDocumentContent(); void SignDocumentContent();
void SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert); void SignDocumentContent(css::uno::Reference<css::security::XCertificate> xCert,
const OUString& aSignatureLineId);
SignatureState GetScriptingSignatureState(); SignatureState GetScriptingSignatureState();
void SignScriptingContent(); void SignScriptingContent();
DECL_LINK(SignDocumentHandler, Button*, void); DECL_LINK(SignDocumentHandler, Button*, void);
@@ -739,9 +740,9 @@ public:
const css::uno::Reference< css::security::XDocumentDigitalSignatures >& xSigner const css::uno::Reference< css::security::XDocumentDigitalSignatures >& xSigner
= css::uno::Reference< css::security::XDocumentDigitalSignatures >() ); = css::uno::Reference< css::security::XDocumentDigitalSignatures >() );
SAL_DLLPRIVATE void SAL_DLLPRIVATE void ImplSign(const css::uno::Reference<css::security::XCertificate> xCert
ImplSign(const css::uno::Reference<css::security::XCertificate> xCert, = css::uno::Reference<css::security::XCertificate>(),
bool bScriptingContent = false); const OUString& aSignatureLineId = OUString(), bool bScriptingContent = false);
SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl( const css::uno::Reference< css::task::XInteractionHandler >& xHandler ); SAL_DLLPRIVATE bool QuerySaveSizeExceededModules_Impl( const css::uno::Reference< css::task::XInteractionHandler >& xHandler );
SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl( const css::uno::Reference< css::task::XInteractionHandler >& xHandler, SAL_DLLPRIVATE bool QueryAllowExoticFormat_Impl( const css::uno::Reference< css::task::XInteractionHandler >& xHandler,

View File

@@ -55,7 +55,8 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface
*/ */
boolean signDocumentContentWithCertificate( [in] ::com::sun::star::embed::XStorage xStorage, boolean signDocumentContentWithCertificate( [in] ::com::sun::star::embed::XStorage xStorage,
[in] ::com::sun::star::io::XStream xSignStream, [in] ::com::sun::star::io::XStream xSignStream,
[in] ::com::sun::star::security::XCertificate xCertificate); [in] ::com::sun::star::security::XCertificate xCertificate,
[in] string signatureLineId);
/** checks for digital signatures and their status. /** checks for digital signatures and their status.

View File

@@ -3661,8 +3661,9 @@ void SfxMedium::CreateTempFileNoCopy()
CloseStorage(); CloseStorage();
} }
bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, bool bScriptingContent, bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, const OUString& aSignatureLineId,
const OUString& aODFVersion, bool bHasValidDocumentSignature) bool bScriptingContent, const OUString& aODFVersion,
bool bHasValidDocumentSignature)
{ {
bool bChanges = false; bool bChanges = false;
@@ -3753,7 +3754,7 @@ bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, bool bScr
bool bSuccess = false; bool bSuccess = false;
if (xCert.is()) if (xCert.is())
bSuccess = xSigner->signDocumentContentWithCertificate( bSuccess = xSigner->signDocumentContentWithCertificate(
GetZipStorageToSign_Impl(), xStream, xCert); GetZipStorageToSign_Impl(), xStream, xCert, aSignatureLineId);
else else
bSuccess = xSigner->signDocumentContent(GetZipStorageToSign_Impl(), bSuccess = xSigner->signDocumentContent(GetZipStorageToSign_Impl(),
xStream); xStream);
@@ -3779,7 +3780,7 @@ bool SfxMedium::SignContents_Impl(const Reference<XCertificate> xCert, bool bScr
if (xCert.is()) if (xCert.is())
{ {
bSuccess = xSigner->signDocumentContentWithCertificate( bSuccess = xSigner->signDocumentContentWithCertificate(
GetZipStorageToSign_Impl(), xStream, xCert); GetZipStorageToSign_Impl(/*bReadOnly=*/false), xStream, xCert, aSignatureLineId);
} }
else else
{ {

View File

@@ -1361,7 +1361,7 @@ SignatureState SfxObjectShell::ImplGetSignatureState( bool bScriptingContent )
return *pState; return *pState;
} }
void SfxObjectShell::ImplSign(Reference<XCertificate> xCert, void SfxObjectShell::ImplSign(Reference<XCertificate> xCert, const OUString& aSignatureLineId,
bool bScriptingContent) bool bScriptingContent)
{ {
// Check if it is stored in OASIS format... // Check if it is stored in OASIS format...
@@ -1488,7 +1488,7 @@ void SfxObjectShell::ImplSign(Reference<XCertificate> xCert,
|| pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK; || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
bool bSignSuccess = GetMedium()->SignContents_Impl( bool bSignSuccess = GetMedium()->SignContents_Impl(
xCert, bScriptingContent, aODFVersion, bHasValidSignatures); xCert, aSignatureLineId, bScriptingContent, aODFVersion, bHasValidSignatures);
pImpl->m_bSavingForSigning = true; pImpl->m_bSavingForSigning = true;
DoSaveCompleted( GetMedium() ); DoSaveCompleted( GetMedium() );
@@ -1523,12 +1523,13 @@ SignatureState SfxObjectShell::GetDocumentSignatureState()
void SfxObjectShell::SignDocumentContent() void SfxObjectShell::SignDocumentContent()
{ {
ImplSign(Reference<XCertificate>()); ImplSign();
} }
void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert) void SfxObjectShell::SignDocumentContent(const Reference<XCertificate> xCert,
const OUString& aSignatureLineId)
{ {
ImplSign(xCert); ImplSign(xCert, aSignatureLineId);
} }
SignatureState SfxObjectShell::GetScriptingSignatureState() SignatureState SfxObjectShell::GetScriptingSignatureState()
@@ -1538,7 +1539,7 @@ SignatureState SfxObjectShell::GetScriptingSignatureState()
void SfxObjectShell::SignScriptingContent() void SfxObjectShell::SignScriptingContent()
{ {
ImplSign( Reference<XCertificate>(), true ); ImplSign( Reference<XCertificate>(), OUString(), true );
} }
namespace namespace

View File

@@ -65,7 +65,8 @@ public:
/// Add a new signature, using xCert as a signing certificate, and rDescription as description. /// Add a new signature, using xCert as a signing certificate, and rDescription as description.
bool add(const css::uno::Reference<css::security::XCertificate>& xCert, bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext, const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant); const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant,
const OUString& rSignatureLineId = OUString());
/// Remove signature at nPosition. /// Remove signature at nPosition.
void remove(sal_uInt16 nPosition); void remove(sal_uInt16 nPosition);
/// Read signatures from either a temp stream or the real storage. /// Read signatures from either a temp stream or the real storage.

View File

@@ -129,6 +129,7 @@ public:
void SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const tools::Time& rTime ); void SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const tools::Time& rTime );
void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription); void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription);
void SetSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId);
void AddForSigning( sal_Int32 securityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF ); void AddForSigning( sal_Int32 securityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF );
void CreateAndWriteSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF ); void CreateAndWriteSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF );

View File

@@ -359,6 +359,7 @@ public:
sal_Int32 nSecurityId, sal_Int32 nSecurityId,
const css::util::DateTime& rDateTime ); const css::util::DateTime& rDateTime );
void setDescription(sal_Int32 nSecurityId, const OUString& rDescription); void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
void setSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId);
bool WriteSignature( bool WriteSignature(
const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,

View File

@@ -107,7 +107,8 @@ public:
sal_Bool SAL_CALL signDocumentContentWithCertificate( sal_Bool SAL_CALL signDocumentContentWithCertificate(
const css::uno::Reference<css::embed::XStorage>& Storage, const css::uno::Reference<css::embed::XStorage>& Storage,
const css::uno::Reference<css::io::XStream>& xSignStream, const css::uno::Reference<css::io::XStream>& xSignStream,
const css::uno::Reference<css::security::XCertificate>& xCertificate) override; const css::uno::Reference<css::security::XCertificate>& xCertificate,
const OUString& rSignatureLineId) override;
css::uno::Sequence<css::security::DocumentSignatureInformation> css::uno::Sequence<css::security::DocumentSignatureInformation>
SAL_CALL verifyDocumentContentSignatures( SAL_CALL verifyDocumentContentSignatures(
const css::uno::Reference<css::embed::XStorage>& xStorage, const css::uno::Reference<css::embed::XStorage>& xStorage,
@@ -225,7 +226,7 @@ sal_Bool DocumentDigitalSignatures::signDocumentContent(
sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate( sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate(
const Reference<css::embed::XStorage>& rxStorage, const Reference<css::embed::XStorage>& rxStorage,
const Reference<css::io::XStream>& xSignStream, const Reference<css::io::XStream>& xSignStream,
const Reference<css::security::XCertificate>& xCertificate) const Reference<css::security::XCertificate>& xCertificate, const OUString& aSignatureLineId)
{ {
OSL_ENSURE(!m_sODFVersion.isEmpty(), OSL_ENSURE(!m_sODFVersion.isEmpty(),
"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2"); "DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
@@ -249,8 +250,8 @@ sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate(
sal_Int32 nSecurityId; sal_Int32 nSecurityId;
OUString aDescription(""); OUString aDescription("");
bool bSuccess bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, aDescription, nSecurityId,
= aSignatureManager.add(xCertificate, xSecurityContext, aDescription, nSecurityId, true); true, aSignatureLineId);
if (!bSuccess) if (!bSuccess)
return false; return false;

View File

@@ -265,7 +265,8 @@ SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int3
bool DocumentSignatureManager::add( bool DocumentSignatureManager::add(
const uno::Reference<security::XCertificate>& xCert, const uno::Reference<security::XCertificate>& xCert,
const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext, const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant) const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant,
const OUString& rSignatureLineId)
{ {
if (!xCert.is()) if (!xCert.is())
{ {
@@ -384,6 +385,9 @@ bool DocumentSignatureManager::add(
tools::Time(tools::Time::SYSTEM)); tools::Time(tools::Time::SYSTEM));
maSignatureHelper.SetDescription(nSecurityId, rDescription); maSignatureHelper.SetDescription(nSecurityId, rDescription);
if (!rSignatureLineId.isEmpty())
maSignatureHelper.SetSignatureLineId(nSecurityId, rSignatureLineId);
// We open a signature stream in which the existing and the new // We open a signature stream in which the existing and the new
//signature is written. ImplGetSignatureInformation (later in this function) will //signature is written. ImplGetSignatureInformation (later in this function) will
//then read the stream and fill maCurrentSignatureInformations. The final signature //then read the stream and fill maCurrentSignatureInformations. The final signature

View File

@@ -350,6 +350,7 @@ void OOXMLSecExporter::Impl::writeSignatureInfo()
m_xDocumentHandler->startElement("SignatureInfoV1", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get())); m_xDocumentHandler->startElement("SignatureInfoV1", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
m_xDocumentHandler->startElement("SetupId", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); m_xDocumentHandler->startElement("SetupId", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
m_xDocumentHandler->characters(m_rInformation.ouSignatureLineId);
m_xDocumentHandler->endElement("SetupId"); m_xDocumentHandler->endElement("SetupId");
m_xDocumentHandler->startElement("SignatureText", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList())); m_xDocumentHandler->startElement("SignatureText", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
m_xDocumentHandler->endElement("SignatureText"); m_xDocumentHandler->endElement("SignatureText");

View File

@@ -149,6 +149,11 @@ void XMLSignatureHelper::SetDescription(sal_Int32 nSecurityId, const OUString& r
mpXSecController->setDescription(nSecurityId, rDescription); mpXSecController->setDescription(nSecurityId, rDescription);
} }
void XMLSignatureHelper::SetSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId)
{
mpXSecController->setSignatureLineId(nSecurityId, rSignatureLineId);
}
void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF ) void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF )
{ {
mpXSecController->signAStream( nSecurityId, uri, bBinary, bXAdESCompliantIfODF ); mpXSecController->signAStream( nSecurityId, uri, bBinary, bXAdESCompliantIfODF );

View File

@@ -856,6 +856,28 @@ void XSecController::exportSignature(
"dc:date"); "dc:date");
} }
xDocumentHandler->endElement( "SignatureProperty" ); xDocumentHandler->endElement( "SignatureProperty" );
if (!signatureInfo.ouSignatureLineId.isEmpty())
{
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute(
"xmlns:loext",
"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0");
pAttributeList->AddAttribute("Target", "#" + signatureInfo.ouSignatureId);
xDocumentHandler->startElement(
"SignatureProperty",
cssu::Reference<cssxs::XAttributeList>(pAttributeList));
{
// Write SignatureLineId element
xDocumentHandler->startElement(
"loext:SignatureLineId",
cssu::Reference<cssxs::XAttributeList>(new SvXMLAttributeList()));
xDocumentHandler->characters(signatureInfo.ouSignatureLineId);
xDocumentHandler->endElement("loext:SignatureLineId");
}
xDocumentHandler->endElement("SignatureProperty");
}
} }
// Write signature description. // Write signature description.

View File

@@ -44,6 +44,7 @@ XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
, m_bInSignatureValue(false) , m_bInSignatureValue(false)
, m_bInDate(false) , m_bInDate(false)
, m_bInDescription(false) , m_bInDescription(false)
, m_bInSignatureLineId(false)
, m_pXSecController(pXSecController) , m_pXSecController(pXSecController)
, m_bReferenceUnresolved(false) , m_bReferenceUnresolved(false)
, m_nReferenceDigestID(cssxc::DigestID::SHA1) , m_nReferenceDigestID(cssxc::DigestID::SHA1)
@@ -259,6 +260,11 @@ void SAL_CALL XSecParser::startElement(
m_ouDescription.clear(); m_ouDescription.clear();
m_bInDescription = true; m_bInDescription = true;
} }
else if (aName == "loext:SignatureLineId")
{
m_ouSignatureLineId.clear();
m_bInSignatureLineId = true;
}
if (m_xNextHandler.is()) if (m_xNextHandler.is())
{ {
@@ -368,6 +374,11 @@ void SAL_CALL XSecParser::endElement( const OUString& aName )
m_pXSecController->setDescription( m_ouDescription ); m_pXSecController->setDescription( m_ouDescription );
m_bInDescription = false; m_bInDescription = false;
} }
else if (aName == "loext:SignatureLineId")
{
m_pXSecController->setSignatureLineId( m_ouSignatureLineId );
m_bInSignatureLineId = false;
}
if (m_xNextHandler.is()) if (m_xNextHandler.is())
{ {
@@ -443,6 +454,10 @@ void SAL_CALL XSecParser::characters( const OUString& aChars )
{ {
m_ouDate += aChars; m_ouDate += aChars;
} }
else if (m_bInSignatureLineId)
{
m_ouSignatureLineId += aChars;
}
if (m_xNextHandler.is()) if (m_xNextHandler.is())
{ {

View File

@@ -67,6 +67,7 @@ private:
OUString m_ouDate; OUString m_ouDate;
/// Characters of a <dc:description> element, as just read from XML. /// Characters of a <dc:description> element, as just read from XML.
OUString m_ouDescription; OUString m_ouDescription;
OUString m_ouSignatureLineId;
/* /*
* whether inside a particular element * whether inside a particular element
@@ -84,6 +85,7 @@ private:
bool m_bInSignatureValue; bool m_bInSignatureValue;
bool m_bInDate; bool m_bInDate;
bool m_bInDescription; bool m_bInDescription;
bool m_bInSignatureLineId;
/* /*
* the XSecController collaborating with XSecParser * the XSecController collaborating with XSecParser

View File

@@ -291,6 +291,23 @@ void XSecController::setDescription(sal_Int32 nSecurityId, const OUString& rDesc
} }
} }
void XSecController::setSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId)
{
int nIndex = findSignatureInfor(nSecurityId);
if (nIndex == -1)
{
InternalSignatureInformation aInformation(nSecurityId, nullptr);
aInformation.signatureInfor.ouSignatureLineId = rSignatureLineId;
m_vInternalSignatureInformations.push_back(aInformation);
}
else
{
SignatureInformation& rInformation = m_vInternalSignatureInformations[nIndex].signatureInfor;
rInformation.ouSignatureLineId = rSignatureLineId;
}
}
bool XSecController::WriteSignature( bool XSecController::WriteSignature(
const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler, const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
bool bXAdESCompliantIfODF ) bool bXAdESCompliantIfODF )