xmlsecurity OOXML export: only cache existing signatures, not our temp. one
When adding a signature, first we export it to a temp. storage, then read it back, show the verification to the user, and then later we do or do not write the temp. storage back to the original one. This means the signature gets exported two times, and MSO only considers the final result valid. So when caching signatures (to avoid a real export based on our data model), don't cache the one we just added to the temp. storage, but do a real export second time as well. With this, MSO considers our appended signature (next to an existing one) valid, too. Change-Id: I4d615298463e037ea4e654ff5c3addcef8b0a094
This commit is contained in:
@@ -54,7 +54,7 @@ public:
|
||||
/// Add a new signature, using xCert as a signing certificate, and rDescription as description.
|
||||
bool add(const css::uno::Reference<css::security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId);
|
||||
/// Read signatures from either a temp stream or the real storage.
|
||||
void read(bool bUseTempStream);
|
||||
void read(bool bUseTempStream, bool bCacheLastSignature = true);
|
||||
};
|
||||
|
||||
#endif // INCLUDED_XMLSECURITY_INC_XMLSECURITY_DOCUMENTSIGNATUREMANAGER_HXX
|
||||
|
@@ -91,7 +91,7 @@ private:
|
||||
DECL_LINK_TYPED(StartVerifySignatureHdl, LinkParamNone*, bool );
|
||||
DECL_LINK_TYPED(OKButtonHdl, Button*, void );
|
||||
|
||||
void ImplGetSignatureInformations(bool bUseTempStream);
|
||||
void ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature = true);
|
||||
void ImplFillSignaturesBox();
|
||||
void ImplShowSignaturesDetails();
|
||||
|
||||
|
@@ -178,7 +178,7 @@ public:
|
||||
static void ExportSignature( const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler, const SignatureInformation& signatureInfo );
|
||||
|
||||
/// Read and verify OOXML signatures.
|
||||
bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage);
|
||||
bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bCacheLastSignature = true);
|
||||
/// Read and verify a single OOXML signature.
|
||||
bool ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream);
|
||||
/// Adds an OOXML digital signature relation to _rels/.rels if there wasn't any before.
|
||||
|
@@ -413,7 +413,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
|
||||
// will not contain
|
||||
// SecurityOperationStatus_OPERATION_SUCCEEDED
|
||||
mbVerifySignatures = true;
|
||||
ImplGetSignatureInformations(true);
|
||||
ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false);
|
||||
ImplFillSignaturesBox();
|
||||
}
|
||||
}
|
||||
@@ -422,7 +422,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
|
||||
{
|
||||
OSL_FAIL( "Exception while adding a signature!" );
|
||||
// Don't keep invalid entries...
|
||||
ImplGetSignatureInformations(true);
|
||||
ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false);
|
||||
ImplFillSignaturesBox();
|
||||
}
|
||||
}
|
||||
@@ -624,9 +624,9 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
|
||||
|
||||
//If bUseTempStream is true then the temporary signature stream is used.
|
||||
//Otherwise the real signature stream is used.
|
||||
void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
|
||||
void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature)
|
||||
{
|
||||
maSignatureManager.read(bUseTempStream);
|
||||
maSignatureManager.read(bUseTempStream, bCacheLastSignature);
|
||||
mbVerifySignatures = false;
|
||||
}
|
||||
|
||||
|
@@ -290,7 +290,7 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
|
||||
return true;
|
||||
}
|
||||
|
||||
void DocumentSignatureManager::read(bool bUseTempStream)
|
||||
void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignature)
|
||||
{
|
||||
maCurrentSignatureInformations.clear();
|
||||
|
||||
@@ -303,7 +303,7 @@ void DocumentSignatureManager::read(bool bUseTempStream)
|
||||
maSignatureHelper.ReadAndVerifySignature(xInputStream);
|
||||
}
|
||||
else if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML && aStreamHelper.xSignatureStorage.is())
|
||||
maSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage);
|
||||
maSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage, bCacheLastSignature);
|
||||
maSignatureHelper.EndMission();
|
||||
|
||||
maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
|
||||
|
@@ -385,7 +385,7 @@ bool lcl_isSignatureOriginType(const beans::StringPair& rPair)
|
||||
}
|
||||
}
|
||||
|
||||
bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage)
|
||||
bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage, bool bCacheLastSignature)
|
||||
{
|
||||
sal_Int32 nOpenMode = embed::ElementModes::READ;
|
||||
uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
|
||||
@@ -393,8 +393,9 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe
|
||||
uno::Sequence< uno::Sequence<beans::StringPair> > aRelationsInfo;
|
||||
aRelationsInfo = comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, "origin.sigs.rels", mxCtx);
|
||||
|
||||
for (const uno::Sequence<beans::StringPair>& rRelation : aRelationsInfo)
|
||||
for (sal_Int32 i = 0; i < aRelationsInfo.getLength(); ++i)
|
||||
{
|
||||
const uno::Sequence<beans::StringPair>& rRelation = aRelationsInfo[i];
|
||||
auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
|
||||
if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureType) != aRelation.end())
|
||||
{
|
||||
@@ -412,17 +413,25 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe
|
||||
if (!ReadAndVerifySignatureStorageStream(xInputStream))
|
||||
return false;
|
||||
|
||||
// Store the contents of the stream as is, in case we need to write it back later.
|
||||
xInputStream.clear();
|
||||
xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
|
||||
uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY);
|
||||
if (xPropertySet.is())
|
||||
// By default, we cache. If it's requested, then we don't cache the last signature.
|
||||
bool bCache = true;
|
||||
if (!bCacheLastSignature && i == aRelationsInfo.getLength() - 1)
|
||||
bCache = false;
|
||||
|
||||
if (bCache)
|
||||
{
|
||||
sal_Int64 nSize = 0;
|
||||
xPropertySet->getPropertyValue("Size") >>= nSize;
|
||||
uno::Sequence<sal_Int8> aData;
|
||||
xInputStream->readBytes(aData, nSize);
|
||||
mpXSecController->setSignatureBytes(aData);
|
||||
// Store the contents of the stream as is, in case we need to write it back later.
|
||||
xInputStream.clear();
|
||||
xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
|
||||
uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY);
|
||||
if (xPropertySet.is())
|
||||
{
|
||||
sal_Int64 nSize = 0;
|
||||
xPropertySet->getPropertyValue("Size") >>= nSize;
|
||||
uno::Sequence<sal_Int8> aData;
|
||||
xInputStream->readBytes(aData, nSize);
|
||||
mpXSecController->setSignatureBytes(aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user