svl/source/crypto/cryptosign.cxx | 12 +-- xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-function-mismatch.pdf |binary xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-hash-mismatch.pdf |binary xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-rsa-mismatch.pdf |binary xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-subfilter-mismatch.pdf |binary xmlsecurity/qa/unit/pdfsigning/data/good-non-detached-mixed.pdf |binary xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx | 33 ++++++++++ 7 files changed, 39 insertions(+), 6 deletions(-)
New commits: commit 6d718cabcc849e271a79b62a42053f58818b41fe Author: Juraj Šarinay <ju...@sarinay.com> AuthorDate: Fri May 9 00:06:52 2025 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue May 13 09:06:45 2025 +0200 Refine the handling of adbe.pkcs7.sha1 signatures when using NSS. Reject signatures with empty encapsulated content. Enforce SHA-1 in the first pass. Change-Id: I42b5f90d02d2abc0c250497d6cc64df4fa798d5d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185207 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 007306c99a42..085c00b86b5d 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -1821,7 +1821,7 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, } HASH_HashType eHashType = HASH_GetHashTypeByOidTag(eOidTag); - HASHContext* pHASHContext = HASH_Create(eHashType); + HASHContext* pHASHContext = HASH_Create(bNonDetached ? HASH_AlgSHA1 : eHashType); if (!pHASHContext) { SAL_WARN("svl.crypto", "ValidateSignature: HASH_Create() failed"); @@ -1927,18 +1927,18 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, SECItem aSignedDigestItem {siBuffer, nullptr, 0}; SECItem* pContentInfoContentData = pCMSSignedData->contentInfo.content.data; - if (bNonDetached && pContentInfoContentData && pContentInfoContentData->data) + if (pContentInfoContentData && pContentInfoContentData->data) { // Not a detached signature. - if (nActualResultLen == pContentInfoContentData->len && - !std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nMaxResultLen) && + if (bNonDetached && nActualResultLen == pContentInfoContentData->len && + !std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nActualResultLen) && HASH_HashBuf(eHashType, pActualResultBuffer, pContentInfoContentData->data, nActualResultLen) == SECSuccess) { aSignedDigestItem.data = pActualResultBuffer; - aSignedDigestItem.len = nActualResultLen; + aSignedDigestItem.len = nMaxResultLen; } } - else + else if (!bNonDetached) { // Detached, the usual case. aSignedDigestItem.data = pActualResultBuffer; diff --git a/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-function-mismatch.pdf b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-function-mismatch.pdf new file mode 100644 index 000000000000..b10aacf3d31e Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-function-mismatch.pdf differ diff --git a/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-hash-mismatch.pdf b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-hash-mismatch.pdf new file mode 100644 index 000000000000..5016da60db5e Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-hash-mismatch.pdf differ diff --git a/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-rsa-mismatch.pdf b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-rsa-mismatch.pdf new file mode 100644 index 000000000000..5a181a24a21d Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-rsa-mismatch.pdf differ diff --git a/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-subfilter-mismatch.pdf b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-subfilter-mismatch.pdf new file mode 100644 index 000000000000..c5d7f0b82aff Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/bad-non-detached-subfilter-mismatch.pdf differ diff --git a/xmlsecurity/qa/unit/pdfsigning/data/good-non-detached-mixed.pdf b/xmlsecurity/qa/unit/pdfsigning/data/good-non-detached-mixed.pdf new file mode 100644 index 000000000000..eb6f8d87be44 Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/good-non-detached-mixed.pdf differ diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index 97d8163b143d..7d176a7e2781 100644 --- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx +++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx @@ -526,6 +526,8 @@ CPPUNIT_TEST_FIXTURE(PDFSigningTest, testGood) const std::initializer_list<std::u16string_view> aNames = { // We failed to determine if this is good or bad. u"good-non-detached.pdf", + // adbe.pcks7.sha1 with SHA-256 in the second pass + u"good-non-detached-mixed.pdf", // Boolean value for dictionary key caused read error. u"dict-bool.pdf", }; @@ -628,6 +630,37 @@ CPPUNIT_TEST_FIXTURE(PDFSigningTest, testGoodCustomMagic) CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size()); } +/// Test that we reject invalid adbe.pkcs7.sha1 +CPPUNIT_TEST_FIXTURE(PDFSigningTest, testBadNonDetached) +{ + std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + { + return; + } + + const std::initializer_list<std::u16string_view> aNames = { + // SHA-1 mismatch + u"bad-non-detached-hash-mismatch.pdf", + // SHA-256 used instead of SHA-1 in the first pass + u"bad-non-detached-function-mismatch.pdf", + // the subfilter says adbe.pkcs7.sha1, the actual signature corresponds to adb.pkcs7.detached + u"bad-non-detached-subfilter-mismatch.pdf", + // CVE-2025-2866; SHA-1 matches, RSA signature invalid + u"bad-non-detached-rsa-mismatch.pdf" + }; + + for (const auto& rName : aNames) + { + std::vector<SignatureInformation> aInfos + = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + rName, 1); + CPPUNIT_ASSERT(!aInfos.empty()); + SignatureInformation& rInformation = aInfos[0]; + CPPUNIT_ASSERT_EQUAL(xml::crypto::SecurityOperationStatus::SecurityOperationStatus_UNKNOWN, + rInformation.nStatus); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */