xmlsecurity PDF verify: support SHA-256

And various other minor fixes.

Change-Id: Ifcccebf48aac8ad526406f2d7a402a840d3c91cd
This commit is contained in:
Miklos Vajna
2016-10-26 17:55:02 +02:00
parent fc56d31c09
commit b6f98b7115
2 changed files with 35 additions and 8 deletions

View File

@@ -75,6 +75,8 @@ public:
static size_t FindStartXRef(SvStream& rStream); static size_t FindStartXRef(SvStream& rStream);
void ReadXRef(SvStream& rStream); void ReadXRef(SvStream& rStream);
static void SkipWhitespace(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; size_t GetObjectOffset(size_t nIndex) const;
const std::vector< std::unique_ptr<PDFElement> >& GetElements(); const std::vector< std::unique_ptr<PDFElement> >& GetElements();
std::vector<PDFObjectElement*> GetPages(); std::vector<PDFObjectElement*> GetPages();

View File

@@ -18,6 +18,7 @@
#include <comphelper/processfactory.hxx> #include <comphelper/processfactory.hxx>
#include <comphelper/scopeguard.hxx> #include <comphelper/scopeguard.hxx>
#include <comphelper/string.hxx> #include <comphelper/string.hxx>
#include <filter/msfilter/mscodec.hxx>
#include <rtl/strbuf.hxx> #include <rtl/strbuf.hxx>
#include <rtl/string.hxx> #include <rtl/string.hxx>
#include <sal/log.hxx> #include <sal/log.hxx>
@@ -784,7 +785,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial)
return false; return false;
} }
PDFDocument::SkipWhitespace(rStream); PDFDocument::SkipLineBreaks(rStream);
m_aElements.push_back(std::unique_ptr<PDFElement>(new PDFStreamElement(nLength))); m_aElements.push_back(std::unique_ptr<PDFElement>(new PDFStreamElement(nLength)));
if (!m_aElements.back()->Read(rStream)) if (!m_aElements.back()->Read(rStream))
return false; return false;
@@ -822,7 +823,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial)
} }
else 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; return false;
} }
} }
@@ -830,7 +831,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, bool bPartial)
{ {
if (!isspace(ch)) 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; 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 size_t PDFDocument::GetObjectOffset(size_t nIndex) const
{ {
auto it = m_aXRef.find(nIndex); auto it = m_aXRef.find(nIndex);
@@ -1388,7 +1407,10 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
switch (SECOID_FindOIDTag(&aAlgorithm)) switch (SECOID_FindOIDTag(&aAlgorithm))
{ {
case SEC_OID_SHA1: case SEC_OID_SHA1:
nMaxResultLen = 20; nMaxResultLen = msfilter::SHA1_HASH_LENGTH;
break;
case SEC_OID_SHA256:
nMaxResultLen = msfilter::SHA256_HASH_LENGTH;
break; break;
default: default:
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: unrecognized algorithm"); SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: unrecognized algorithm");
@@ -1519,14 +1541,14 @@ bool PDFNumberElement::Read(SvStream& rStream)
m_nOffset = rStream.Tell(); m_nOffset = rStream.Tell();
char ch; char ch;
rStream.ReadChar(ch); rStream.ReadChar(ch);
if (!isdigit(ch) && ch != '-') if (!isdigit(ch) && ch != '-' && ch != '.')
{ {
rStream.SeekRel(-1); rStream.SeekRel(-1);
return false; return false;
} }
while (!rStream.IsEof()) while (!rStream.IsEof())
{ {
if (!isdigit(ch) && ch != '-') if (!isdigit(ch) && ch != '-' && ch != '.')
{ {
rStream.SeekRel(-1); rStream.SeekRel(-1);
m_nLength = rStream.Tell() - m_nOffset; m_nLength = rStream.Tell() - m_nOffset;
@@ -1599,25 +1621,28 @@ const OString& PDFHexStringElement::GetValue() const
bool PDFLiteralStringElement::Read(SvStream& rStream) bool PDFLiteralStringElement::Read(SvStream& rStream)
{ {
char ch; char nPrevCh = 0;
char ch = 0;
rStream.ReadChar(ch); rStream.ReadChar(ch);
if (ch != '(') if (ch != '(')
{ {
SAL_INFO("xmlsecurity.pdfio", "PDFHexStringElement::Read: expected '(' as first character"); SAL_INFO("xmlsecurity.pdfio", "PDFHexStringElement::Read: expected '(' as first character");
return false; return false;
} }
nPrevCh = ch;
rStream.ReadChar(ch); rStream.ReadChar(ch);
OStringBuffer aBuf; OStringBuffer aBuf;
while (!rStream.IsEof()) while (!rStream.IsEof())
{ {
if (ch == ')') if (ch == ')' && nPrevCh != '\\')
{ {
m_aValue = aBuf.makeStringAndClear(); m_aValue = aBuf.makeStringAndClear();
SAL_INFO("xmlsecurity.pdfio", "PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'"); SAL_INFO("xmlsecurity.pdfio", "PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'");
return true; return true;
} }
aBuf.append(ch); aBuf.append(ch);
nPrevCh = ch;
rStream.ReadChar(ch); rStream.ReadChar(ch);
} }