summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-10-27 17:01:09 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-10-27 17:01:09 +0200
commit9df81ea7752216db7a7cf54df1b307d97e51b1a3 (patch)
treec107cb4bd3618dc479f0ed0452f684e83ca3bd52 /xmlsecurity
parent090e666c127e81ed47338034796f574bbbddfb73 (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.cxx15
-rw-r--r--xmlsecurity/source/pdfio/pdfdocument.cxx24
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)
{