From b6f98b71155d3c7af70bfc623cfaa7da0fbb905f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 26 Oct 2016 17:55:02 +0200 Subject: [PATCH] xmlsecurity PDF verify: support SHA-256 And various other minor fixes. Change-Id: Ifcccebf48aac8ad526406f2d7a402a840d3c91cd --- xmlsecurity/inc/pdfio/pdfdocument.hxx | 2 ++ xmlsecurity/source/pdfio/pdfdocument.cxx | 41 +++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/xmlsecurity/inc/pdfio/pdfdocument.hxx b/xmlsecurity/inc/pdfio/pdfdocument.hxx index f42350ac5a20..8ef7afdf2c66 100644 --- a/xmlsecurity/inc/pdfio/pdfdocument.hxx +++ b/xmlsecurity/inc/pdfio/pdfdocument.hxx @@ -75,6 +75,8 @@ public: static size_t FindStartXRef(SvStream& rStream); void ReadXRef(SvStream& rStream); static void SkipWhitespace(SvStream& rStream); + /// Instead of all whitespace, just skip CR and NL characters. + static void SkipLineBreaks(SvStream& rStream); size_t GetObjectOffset(size_t nIndex) const; const std::vector< std::unique_ptr >& GetElements(); std::vector GetPages(); diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index a1ac63c2ef6e..df7a8091bcd7 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -784,7 +785,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial) return false; } - PDFDocument::SkipWhitespace(rStream); + PDFDocument::SkipLineBreaks(rStream); m_aElements.push_back(std::unique_ptr(new PDFStreamElement(nLength))); if (!m_aElements.back()->Read(rStream)) return false; @@ -822,7 +823,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial) } else { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: unexpected '" << aKeyword << "' keyword"); + SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: unexpected '" << aKeyword << "' keyword at byte position " << rStream.Tell()); return false; } } @@ -830,7 +831,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial) { if (!isspace(ch)) { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: unexpected character: " << ch); + SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: unexpected character: " << ch << " at byte position " << rStream.Tell()); return false; } } @@ -1034,6 +1035,24 @@ void PDFDocument::SkipWhitespace(SvStream& rStream) } } +void PDFDocument::SkipLineBreaks(SvStream& rStream) +{ + char ch = 0; + + while (true) + { + rStream.ReadChar(ch); + if (rStream.IsEof()) + break; + + if (ch != '\n' && ch != '\r') + { + rStream.SeekRel(-1); + return; + } + } +} + size_t PDFDocument::GetObjectOffset(size_t nIndex) const { auto it = m_aXRef.find(nIndex); @@ -1388,7 +1407,10 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat switch (SECOID_FindOIDTag(&aAlgorithm)) { case SEC_OID_SHA1: - nMaxResultLen = 20; + nMaxResultLen = msfilter::SHA1_HASH_LENGTH; + break; + case SEC_OID_SHA256: + nMaxResultLen = msfilter::SHA256_HASH_LENGTH; break; default: SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: unrecognized algorithm"); @@ -1519,14 +1541,14 @@ bool PDFNumberElement::Read(SvStream& rStream) m_nOffset = rStream.Tell(); char ch; rStream.ReadChar(ch); - if (!isdigit(ch) && ch != '-') + if (!isdigit(ch) && ch != '-' && ch != '.') { rStream.SeekRel(-1); return false; } while (!rStream.IsEof()) { - if (!isdigit(ch) && ch != '-') + if (!isdigit(ch) && ch != '-' && ch != '.') { rStream.SeekRel(-1); m_nLength = rStream.Tell() - m_nOffset; @@ -1599,25 +1621,28 @@ const OString& PDFHexStringElement::GetValue() const bool PDFLiteralStringElement::Read(SvStream& rStream) { - char ch; + char nPrevCh = 0; + char ch = 0; rStream.ReadChar(ch); if (ch != '(') { SAL_INFO("xmlsecurity.pdfio", "PDFHexStringElement::Read: expected '(' as first character"); return false; } + nPrevCh = ch; rStream.ReadChar(ch); OStringBuffer aBuf; while (!rStream.IsEof()) { - if (ch == ')') + if (ch == ')' && nPrevCh != '\\') { m_aValue = aBuf.makeStringAndClear(); SAL_INFO("xmlsecurity.pdfio", "PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'"); return true; } aBuf.append(ch); + nPrevCh = ch; rStream.ReadChar(ch); }