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: */

Reply via email to