xmlsecurity PDF sign: support non-compressed AcroForm objects
This was the last problem to be able to counter-sign Acrobat-created PDF 1.6 signatures unlimited number of times. Change-Id: I24ab80c8516b6fe9c08d57c08907bec70384dc28 Reviewed-on: https://gerrit.libreoffice.org/30757 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
This commit is contained in:
@@ -283,7 +283,14 @@ void PDFSigningTest::testPDF16Add()
|
|||||||
OUString aOutURL = aTargetDir + "add.pdf";
|
OUString aOutURL = aTargetDir + "add.pdf";
|
||||||
// This failed: verification broke as incorrect xref stream was written as
|
// This failed: verification broke as incorrect xref stream was written as
|
||||||
// part of the new signature.
|
// part of the new signature.
|
||||||
sign(aInURL, aOutURL, 1);
|
bool bHadCertificates = sign(aInURL, aOutURL, 1);
|
||||||
|
|
||||||
|
// Sign again.
|
||||||
|
aInURL = aTargetDir + "add.pdf";
|
||||||
|
aOutURL = aTargetDir + "add2.pdf";
|
||||||
|
// This failed as non-compressed AcroForm wasn't handled.
|
||||||
|
if (bHadCertificates)
|
||||||
|
sign(aInURL, aOutURL, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFSigningTest::testPDF14LOWin()
|
void PDFSigningTest::testPDF14LOWin()
|
||||||
|
@@ -600,12 +600,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
|
|||||||
m_aEditBuffer.WriteUInt32AsString(nAcroFormId);
|
m_aEditBuffer.WriteUInt32AsString(nAcroFormId);
|
||||||
m_aEditBuffer.WriteCharPtr(" 0 obj\n");
|
m_aEditBuffer.WriteCharPtr(" 0 obj\n");
|
||||||
|
|
||||||
|
// If this is nullptr, then the AcroForm object is not in an object stream.
|
||||||
SvMemoryStream* pStreamBuffer = pAcroFormObject->GetStreamBuffer();
|
SvMemoryStream* pStreamBuffer = pAcroFormObject->GetStreamBuffer();
|
||||||
if (!pStreamBuffer)
|
|
||||||
{
|
|
||||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: AcroForm object is not in an object stream");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pAcroFormObject->Lookup("Fields"))
|
if (!pAcroFormObject->Lookup("Fields"))
|
||||||
{
|
{
|
||||||
@@ -624,7 +620,14 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
|
|||||||
sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields") + pAcroFormDictionary->GetKeyValueLength("Fields") - strlen("]");
|
sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields") + pAcroFormDictionary->GetKeyValueLength("Fields") - strlen("]");
|
||||||
// Length of beginning of the object dictionary -> Fields end.
|
// Length of beginning of the object dictionary -> Fields end.
|
||||||
sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset;
|
sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset;
|
||||||
m_aEditBuffer.WriteBytes(pStreamBuffer->GetData(), nFieldsBeforeEndLength);
|
if (pStreamBuffer)
|
||||||
|
m_aEditBuffer.WriteBytes(pStreamBuffer->GetData(), nFieldsBeforeEndLength);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nFieldsBeforeEndLength -= pAcroFormObject->GetDictionaryOffset();
|
||||||
|
m_aEditBuffer.WriteCharPtr("<<");
|
||||||
|
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + pAcroFormObject->GetDictionaryOffset(), nFieldsBeforeEndLength);
|
||||||
|
}
|
||||||
|
|
||||||
// Append our reference at the end of the Fields array.
|
// Append our reference at the end of the Fields array.
|
||||||
m_aEditBuffer.WriteCharPtr(" ");
|
m_aEditBuffer.WriteCharPtr(" ");
|
||||||
@@ -632,8 +635,17 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
|
|||||||
m_aEditBuffer.WriteCharPtr(" 0 R");
|
m_aEditBuffer.WriteCharPtr(" 0 R");
|
||||||
|
|
||||||
// Length of Fields end -> end of the object dictionary.
|
// Length of Fields end -> end of the object dictionary.
|
||||||
sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset;
|
if (pStreamBuffer)
|
||||||
m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
|
{
|
||||||
|
sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset;
|
||||||
|
m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sal_uInt64 nFieldsAfterEndLength = pAcroFormObject->GetDictionaryOffset() + pAcroFormObject->GetDictionaryLength() - nFieldsEndOffset;
|
||||||
|
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
|
||||||
|
m_aEditBuffer.WriteCharPtr(">>");
|
||||||
|
}
|
||||||
|
|
||||||
m_aEditBuffer.WriteCharPtr("\nendobj\n\n");
|
m_aEditBuffer.WriteCharPtr("\nendobj\n\n");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user