summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-10-19 16:50:07 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-10-20 00:50:37 +0200
commit586f6abee92af3cdabdce034b607b9a046ed3946 (patch)
treea0b7dbed12b25caf4ef401d5d15a81ef928f3938 /xmlsecurity
parent326c8d06070a4a41a666db919702f7c423dc7a18 (diff)
xmlsecurity: handle MDP permission during PDF verify
Change-Id: I626fca7c03079fb0374c577dcfe024e7db6ed5b3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104529 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/qa/unit/pdfsigning/data/bad-cert-p1.pdfbin0 -> 29646 bytes
-rw-r--r--xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx14
-rw-r--r--xmlsecurity/source/helper/pdfsignaturehelper.cxx22
3 files changed, 27 insertions, 9 deletions
diff --git a/xmlsecurity/qa/unit/pdfsigning/data/bad-cert-p1.pdf b/xmlsecurity/qa/unit/pdfsigning/data/bad-cert-p1.pdf
new file mode 100644
index 000000000000..04d9950582b0
--- /dev/null
+++ b/xmlsecurity/qa/unit/pdfsigning/data/bad-cert-p1.pdf
Binary files differ
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index 586ef54d3075..78c564b26e28 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -388,6 +388,20 @@ CPPUNIT_TEST_FIXTURE(PDFSigningTest, testPartialInBetween)
CPPUNIT_ASSERT(rInformation.bPartialDocumentSignature);
}
+CPPUNIT_TEST_FIXTURE(PDFSigningTest, testBadCertP1)
+{
+ std::vector<SignatureInformation> aInfos
+ = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "bad-cert-p1.pdf", 1);
+ CPPUNIT_ASSERT(!aInfos.empty());
+ SignatureInformation& rInformation = aInfos[0];
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0 (SecurityOperationStatus_UNKNOWN)
+ // - Actual : 1 (SecurityOperationStatus_OPERATION_SUCCEEDED)
+ // i.e. annotation after a P1 signature was not considered as a bad modification.
+ CPPUNIT_ASSERT_EQUAL(xml::crypto::SecurityOperationStatus::SecurityOperationStatus_UNKNOWN,
+ rInformation.nStatus);
+}
+
/// Test writing a PAdES signature.
CPPUNIT_TEST_FIXTURE(PDFSigningTest, testSigningCertificateAttribute)
{
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
index 3942163e970c..a1dde44aaeb7 100644
--- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -227,7 +227,8 @@ bool IsCompleteSignature(SvStream& rStream, vcl::filter::PDFDocument& rDocument,
#if HAVE_FEATURE_PDFIUM
/// Collects the checksum of each page of one version of the PDF.
-void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum>& rPageChecksums)
+void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum>& rPageChecksums,
+ int nMDPPerm)
{
auto pPdfium = vcl::pdf::PDFiumLibrary::get();
vcl::pdf::PDFiumDocument aPdfDocument(
@@ -242,7 +243,7 @@ void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum
return;
}
- BitmapChecksum nPageChecksum = pPdfPage->getChecksum();
+ BitmapChecksum nPageChecksum = pPdfPage->getChecksum(nMDPPerm);
rPageChecksums.push_back(nPageChecksum);
}
}
@@ -250,9 +251,9 @@ void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum
/**
* Checks if incremental updates after singing performed valid modifications only.
- * Annotations/commenting is OK, other changes are not.
+ * nMDPPerm decides if annotations/commenting is OK, other changes are always not.
*/
-bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature)
+bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, int nMDPPerm)
{
size_t nSignatureEOF = 0;
if (!GetEOFOfSignature(pSignature, nSignatureEOF))
@@ -268,7 +269,7 @@ bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignatu
rStream.Seek(nPos);
aSignatureStream.Seek(0);
std::vector<BitmapChecksum> aSignedPages;
- AnalyizeSignatureStream(aSignatureStream, aSignedPages);
+ AnalyizeSignatureStream(aSignatureStream, aSignedPages, nMDPPerm);
SvMemoryStream aFullStream;
nPos = rStream.Tell();
@@ -277,7 +278,7 @@ bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignatu
rStream.Seek(nPos);
aFullStream.Seek(0);
std::vector<BitmapChecksum> aAllPages;
- AnalyizeSignatureStream(aFullStream, aAllPages);
+ AnalyizeSignatureStream(aFullStream, aAllPages, nMDPPerm);
// Fail if any page looks different after signing and at the end. Annotations/commenting doesn't
// count, though.
@@ -294,7 +295,8 @@ bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignatu
* @return If we can determinate a result.
*/
bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature,
- SignatureInformation& rInformation, vcl::filter::PDFDocument& rDocument)
+ SignatureInformation& rInformation, vcl::filter::PDFDocument& rDocument,
+ int nMDPPerm)
{
vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V");
if (!pValue)
@@ -401,7 +403,7 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
return false;
}
rInformation.bPartialDocumentSignature = !IsCompleteSignature(rStream, rDocument, pSignature);
- if (!IsValidSignature(rStream, pSignature))
+ if (!IsValidSignature(rStream, pSignature, nMDPPerm))
{
SAL_WARN("xmlsecurity.helper", "ValidateSignature: invalid incremental update detected");
return false;
@@ -451,11 +453,13 @@ bool PDFSignatureHelper::ReadAndVerifySignatureSvStream(SvStream& rStream)
m_aSignatureInfos.clear();
+ int nMDPPerm = aDocument.GetMDPPerm();
+
for (size_t i = 0; i < aSignatures.size(); ++i)
{
SignatureInformation aInfo(i);
- if (!ValidateSignature(rStream, aSignatures[i], aInfo, aDocument))
+ if (!ValidateSignature(rStream, aSignatures[i], aInfo, aDocument, nMDPPerm))
SAL_WARN("xmlsecurity.helper", "failed to determine digest match");
m_aSignatureInfos.push_back(aInfo);