diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-10-27 17:01:09 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-10-27 17:01:09 +0200 |
commit | 9df81ea7752216db7a7cf54df1b307d97e51b1a3 (patch) | |
tree | c107cb4bd3618dc479f0ed0452f684e83ca3bd52 /xmlsecurity | |
parent | 090e666c127e81ed47338034796f574bbbddfb73 (diff) |
xmlsecurity PDF verify: import out-of-signature date
The signature date can be placed as the value of the "M" key, and also
inside the signed PKCS#7 binary. When the later is missing show what's
described in the previous.
Change-Id: Idb40d91adb70486bc1f19d4755a3f8e17d35e9e9
Diffstat (limited to 'xmlsecurity')
-rw-r--r-- | xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx | 15 | ||||
-rw-r--r-- | xmlsecurity/source/pdfio/pdfdocument.cxx | 24 |
2 files changed, 36 insertions, 3 deletions
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index 62855c4527a6..5ee13221fdab 100644 --- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx +++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx @@ -41,7 +41,7 @@ class PDFSigningTest : public test::BootstrapFixture * Read a pdf and make sure that it has the expected number of valid * signatures. */ - void verify(const OUString& rURL, size_t nCount); + std::vector<SignatureInformation> verify(const OUString& rURL, size_t nCount); public: PDFSigningTest(); @@ -90,8 +90,12 @@ void PDFSigningTest::setUp() #endif } -void PDFSigningTest::verify(const OUString& rURL, size_t nCount) +std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, size_t nCount) { + uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); + uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); + std::vector<SignatureInformation> aRet; + SvFileStream aStream(rURL, StreamMode::READ); xmlsecurity::pdfio::PDFDocument aVerifyDocument; CPPUNIT_ASSERT(aVerifyDocument.Read(aStream)); @@ -102,7 +106,10 @@ void PDFSigningTest::verify(const OUString& rURL, size_t nCount) SignatureInformation aInfo(i); bool bLast = i == aSignatures.size() - 1; CPPUNIT_ASSERT(xmlsecurity::pdfio::PDFDocument::ValidateSignature(aStream, aSignatures[i], aInfo, bLast)); + aRet.push_back(aInfo); } + + return aRet; } void PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_t nOriginalSignatureCount) @@ -241,7 +248,9 @@ void PDFSigningTest::testPDF14Adobe() // Two signatures, first is SHA1, the second is SHA256. // This was 0, as we failed to find the Annots key's value when it was a // reference-to-array, not an array. - verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14adobe.pdf", 2); + std::vector<SignatureInformation> aInfos = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14adobe.pdf", 2); + // This was 0, out-of-PKCS#7 signature date wasn't read. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2016), aInfos[1].stDateTime.Year); #endif } diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index adbf51bf893f..a0e00ef8f3f5 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -258,6 +258,7 @@ class PDFLiteralStringElement : public PDFElement OString m_aValue; public: bool Read(SvStream& rStream) override; + const OString& GetValue() const; }; /// The trailer singleton is at the end of the doc. @@ -1314,6 +1315,24 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat rInformation.ouDescription = aBuffer.makeStringAndClear(); } + // Date: used only when the time of signing is not available in the + // signature. + auto pM = dynamic_cast<PDFLiteralStringElement*>(pValue->Lookup("M")); + if (pM) + { + // Example: "D:20161027100104". + const OString& rM = pM->GetValue(); + if (rM.startsWith("D:") && rM.getLength() >= 16) + { + rInformation.stDateTime.Year = rM.copy(2, 4).toInt32(); + rInformation.stDateTime.Month = rM.copy(6, 2).toInt32(); + rInformation.stDateTime.Day = rM.copy(8, 2).toInt32(); + rInformation.stDateTime.Hours = rM.copy(10, 2).toInt32(); + rInformation.stDateTime.Minutes = rM.copy(12, 2).toInt32(); + rInformation.stDateTime.Seconds = rM.copy(14, 2).toInt32(); + } + } + // Build a list of offset-length pairs, representing the signed bytes. std::vector<std::pair<size_t, size_t>> aByteRanges; size_t nByteRangeOffset = 0; @@ -1697,6 +1716,11 @@ bool PDFLiteralStringElement::Read(SvStream& rStream) return false; } +const OString& PDFLiteralStringElement::GetValue() const +{ + return m_aValue; +} + PDFTrailerElement::PDFTrailerElement(PDFDocument& rDoc) : m_rDoc(rDoc) { |