Kaydet (Commit) 9df81ea7 authored tarafından Miklos Vajna's avatar Miklos Vajna

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
üst 090e666c
...@@ -41,7 +41,7 @@ class PDFSigningTest : public test::BootstrapFixture ...@@ -41,7 +41,7 @@ class PDFSigningTest : public test::BootstrapFixture
* Read a pdf and make sure that it has the expected number of valid * Read a pdf and make sure that it has the expected number of valid
* signatures. * signatures.
*/ */
void verify(const OUString& rURL, size_t nCount); std::vector<SignatureInformation> verify(const OUString& rURL, size_t nCount);
public: public:
PDFSigningTest(); PDFSigningTest();
...@@ -90,8 +90,12 @@ void PDFSigningTest::setUp() ...@@ -90,8 +90,12 @@ void PDFSigningTest::setUp()
#endif #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); SvFileStream aStream(rURL, StreamMode::READ);
xmlsecurity::pdfio::PDFDocument aVerifyDocument; xmlsecurity::pdfio::PDFDocument aVerifyDocument;
CPPUNIT_ASSERT(aVerifyDocument.Read(aStream)); CPPUNIT_ASSERT(aVerifyDocument.Read(aStream));
...@@ -102,7 +106,10 @@ void PDFSigningTest::verify(const OUString& rURL, size_t nCount) ...@@ -102,7 +106,10 @@ void PDFSigningTest::verify(const OUString& rURL, size_t nCount)
SignatureInformation aInfo(i); SignatureInformation aInfo(i);
bool bLast = i == aSignatures.size() - 1; bool bLast = i == aSignatures.size() - 1;
CPPUNIT_ASSERT(xmlsecurity::pdfio::PDFDocument::ValidateSignature(aStream, aSignatures[i], aInfo, bLast)); 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) void PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_t nOriginalSignatureCount)
...@@ -241,7 +248,9 @@ void PDFSigningTest::testPDF14Adobe() ...@@ -241,7 +248,9 @@ void PDFSigningTest::testPDF14Adobe()
// Two signatures, first is SHA1, the second is SHA256. // 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 // This was 0, as we failed to find the Annots key's value when it was a
// reference-to-array, not an array. // 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 #endif
} }
......
...@@ -258,6 +258,7 @@ class PDFLiteralStringElement : public PDFElement ...@@ -258,6 +258,7 @@ class PDFLiteralStringElement : public PDFElement
OString m_aValue; OString m_aValue;
public: public:
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
const OString& GetValue() const;
}; };
/// The trailer singleton is at the end of the doc. /// The trailer singleton is at the end of the doc.
...@@ -1314,6 +1315,24 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat ...@@ -1314,6 +1315,24 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
rInformation.ouDescription = aBuffer.makeStringAndClear(); 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. // Build a list of offset-length pairs, representing the signed bytes.
std::vector<std::pair<size_t, size_t>> aByteRanges; std::vector<std::pair<size_t, size_t>> aByteRanges;
size_t nByteRangeOffset = 0; size_t nByteRangeOffset = 0;
...@@ -1697,6 +1716,11 @@ bool PDFLiteralStringElement::Read(SvStream& rStream) ...@@ -1697,6 +1716,11 @@ bool PDFLiteralStringElement::Read(SvStream& rStream)
return false; return false;
} }
const OString& PDFLiteralStringElement::GetValue() const
{
return m_aValue;
}
PDFTrailerElement::PDFTrailerElement(PDFDocument& rDoc) PDFTrailerElement::PDFTrailerElement(PDFDocument& rDoc)
: m_rDoc(rDoc) : m_rDoc(rDoc)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment