diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-11-04 21:39:04 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-11-05 09:04:29 +0100 |
commit | f231dacde9df1c4aa5f4e0970535c4f4093364a7 (patch) | |
tree | 0bb3156eeb65d8e9235450af190522878e022559 /xmlsecurity/source/helper | |
parent | d261356266f9b3c2fd4ec487ba260f31d53f5015 (diff) |
xmlsecurity: reject a few dangerous annotation types during pdf sig verify
Change-Id: I950b49a6e7181639daf27348ddfa0f36586baa65
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105312
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'xmlsecurity/source/helper')
-rw-r--r-- | xmlsecurity/source/helper/pdfsignaturehelper.cxx | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx index f7427337fd1e..72f7618a2253 100644 --- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx +++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx @@ -226,8 +226,30 @@ bool IsCompleteSignature(SvStream& rStream, vcl::filter::PDFDocument& rDocument, } #if HAVE_FEATURE_PDFIUM + +/** + * Contains checksums of a PDF page, which is rendered without annotations. It also contains + * the geometry of a few dangerous annotation types. + */ +struct PageChecksum +{ + BitmapChecksum m_nPageContent; + std::vector<basegfx::B2DRectangle> m_aAnnotations; + bool operator==(const PageChecksum& rChecksum) const; +}; + +bool PageChecksum::operator==(const PageChecksum& rChecksum) const +{ + if (m_nPageContent != rChecksum.m_nPageContent) + { + return false; + } + + return m_aAnnotations == rChecksum.m_aAnnotations; +} + /// 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<PageChecksum>& rPageChecksums, int nMDPPerm) { auto pPdfium = vcl::pdf::PDFiumLibrary::get(); @@ -247,8 +269,25 @@ void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum return; } - BitmapChecksum nPageChecksum = pPdfPage->getChecksum(nMDPPerm); - rPageChecksums.push_back(nPageChecksum); + PageChecksum aPageChecksum; + aPageChecksum.m_nPageContent = pPdfPage->getChecksum(nMDPPerm); + for (int i = 0; i < pPdfPage->getAnnotationCount(); ++i) + { + std::unique_ptr<vcl::pdf::PDFiumAnnotation> pPdfAnnotation = pPdfPage->getAnnotation(i); + vcl::pdf::PDFAnnotationSubType eType = pPdfAnnotation->getSubType(); + switch (eType) + { + case vcl::pdf::PDFAnnotationSubType::Unknown: + case vcl::pdf::PDFAnnotationSubType::FreeText: + case vcl::pdf::PDFAnnotationSubType::Stamp: + case vcl::pdf::PDFAnnotationSubType::Redact: + aPageChecksum.m_aAnnotations.push_back(pPdfAnnotation->getRectangle()); + break; + default: + break; + } + } + rPageChecksums.push_back(aPageChecksum); } } #endif @@ -272,7 +311,7 @@ bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignatu aSignatureStream.WriteStream(rStream, nSignatureEOF); rStream.Seek(nPos); aSignatureStream.Seek(0); - std::vector<BitmapChecksum> aSignedPages; + std::vector<PageChecksum> aSignedPages; AnalyizeSignatureStream(aSignatureStream, aSignedPages, nMDPPerm); SvMemoryStream aFullStream; @@ -281,7 +320,7 @@ bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignatu aFullStream.WriteStream(rStream); rStream.Seek(nPos); aFullStream.Seek(0); - std::vector<BitmapChecksum> aAllPages; + std::vector<PageChecksum> aAllPages; AnalyizeSignatureStream(aFullStream, aAllPages, nMDPPerm); // Fail if any page looks different after signing and at the end. Annotations/commenting doesn't |