qt5/tests/CMakeLists.txt             |    1 
 qt5/tests/check_signature_basics.cpp |  133 +++++++++++++++++++++++++++++++++++
 qt6/tests/CMakeLists.txt             |    1 
 qt6/tests/check_signature_basics.cpp |  133 +++++++++++++++++++++++++++++++++++
 4 files changed, 268 insertions(+)

New commits:
commit e4f80d6461cc26e2dd1494ab2bf548e3382a5153
Author: Sune Vuorela <s...@vuorela.dk>
Date:   Wed Mar 15 12:22:00 2023 +0100

    Simple signature tests
    
    Document some of the fields we can extract.

diff --git a/qt5/tests/CMakeLists.txt b/qt5/tests/CMakeLists.txt
index baadd428..3e3be3e0 100644
--- a/qt5/tests/CMakeLists.txt
+++ b/qt5/tests/CMakeLists.txt
@@ -70,6 +70,7 @@ qt5_add_qtest(check_qt5_object check_object.cpp)
 qt5_add_qtest(check_qt5_stroke_opacity check_stroke_opacity.cpp)
 qt5_add_qtest(check_qt5_utf_conversion check_utf_conversion.cpp)
 qt5_add_qtest(check_qt5_outline check_outline.cpp)
+qt5_add_qtest(check_qt5_signature_basics check_signature_basics.cpp)
 if (NOT WIN32)
   qt5_add_qtest(check_qt5_pagelabelinfo check_pagelabelinfo.cpp)
   qt5_add_qtest(check_qt5_strings check_strings.cpp)
diff --git a/qt5/tests/check_signature_basics.cpp 
b/qt5/tests/check_signature_basics.cpp
new file mode 100644
index 00000000..7cdb1c37
--- /dev/null
+++ b/qt5/tests/check_signature_basics.cpp
@@ -0,0 +1,133 @@
+//========================================================================
+//
+// check_signature_basics.cpp
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright 2023 g10 Code GmbH, Author: Sune Stolborg Vuorela 
<s...@vuorela.dk>
+//========================================================================
+
+// Simple tests of reading signatures
+//
+// Note that this does not check the actual validity because
+// that will have an expiry date, and adding time bombs to unit tests is
+// probably not a good idea.
+#include <QtTest/QtTest>
+#include "PDFDoc.h"
+#include "GlobalParams.h"
+#include "SignatureInfo.h"
+#include "config.h"
+
+class TestSignatureBasics : public QObject
+{
+    Q_OBJECT
+public:
+    explicit TestSignatureBasics(QObject *parent = nullptr) : QObject(parent) 
{ }
+
+private:
+    std::unique_ptr<PDFDoc> doc;
+private Q_SLOTS:
+    void initTestCase();
+    void cleanupTestCase();
+    void testSignatureCount();
+    void testSignatureSizes();
+    void testSignerInfo(); // names and stuff
+    void testSignedRanges();
+};
+
+void TestSignatureBasics::initTestCase()
+{
+    globalParams = std::make_unique<GlobalParams>();
+    doc = std::make_unique<PDFDoc>(std::make_unique<GooString>(TESTDATADIR 
"/unittestcases/pdf-signature-sample-2sigs.pdf"));
+    QVERIFY(doc);
+    QVERIFY(doc->isOk());
+}
+void TestSignatureBasics::cleanupTestCase()
+{
+    globalParams.reset();
+}
+
+void TestSignatureBasics::testSignatureCount()
+{
+    QVERIFY(doc);
+    auto signatureFields = doc->getSignatureFields();
+    QCOMPARE(signatureFields.size(), 4);
+    // count active signatures
+    QVERIFY(signatureFields[0]->getSignature());
+    QVERIFY(signatureFields[1]->getSignature());
+    QVERIFY(!signatureFields[2]->getSignature());
+    QVERIFY(!signatureFields[3]->getSignature());
+}
+
+void TestSignatureBasics::testSignatureSizes()
+{
+    auto signatureFields = doc->getSignatureFields();
+    // Note for later. Unpadding a signature on a command line with openssl can
+    // be done just by rewriting after using e.g. pdfsig -dump to extract them
+    // openssl pkcs7 -inform der -in pdf-signature-sample-2sigs.pdf.sig0 
-outform der -out pdf-signature-sample-2sigs.pdf.sig0.unpadded
+    QCOMPARE(signatureFields[0]->getSignature()->getLength(), 10230); // This 
is technically wrong, because the signatures in this document has been padded. 
The correct size is 2340
+    QCOMPARE(signatureFields[1]->getSignature()->getLength(), 10196); // This 
is technically wrong, because the signatures in this document has been padded. 
The correct size is 2340
+}
+
+void TestSignatureBasics::testSignerInfo()
+{
+    auto signatureFields = doc->getSignatureFields();
+    
QCOMPARE(signatureFields[0]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature0_B_" });
+    QCOMPARE(signatureFields[0]->getSignatureType(), ETSI_CAdES_detached);
+    auto siginfo0 = signatureFields[0]->validateSignature(false, false, -1 /* 
now */, false, false);
+#ifdef ENABLE_NSS3
+    QCOMPARE(siginfo0->getSignerName(), std::string { "Koch, Werner" });
+    QCOMPARE(siginfo0->getHashAlgorithm(), HashAlgorithm::Sha256);
+#else
+    QCOMPARE(siginfo0->getSignerName(), std::string {});
+    QCOMPARE(siginfo0->getHashAlgorithm(), HashAlgorithm::Unknown);
+#endif
+    QCOMPARE(siginfo0->getSigningTime(), time_t(1677570911));
+
+    
QCOMPARE(signatureFields[1]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature1_B_" });
+    QCOMPARE(signatureFields[1]->getSignatureType(), ETSI_CAdES_detached);
+    auto siginfo1 = signatureFields[1]->validateSignature(false, false, -1 /* 
now */, false, false);
+#ifdef ENABLE_NSS3
+    QCOMPARE(siginfo1->getSignerName(), std::string { "Koch, Werner" });
+    QCOMPARE(siginfo1->getHashAlgorithm(), HashAlgorithm::Sha256);
+#else
+    QCOMPARE(siginfo1->getSignerName(), std::string {});
+    QCOMPARE(siginfo1->getHashAlgorithm(), HashAlgorithm::Unknown);
+#endif
+    QCOMPARE(siginfo1->getSigningTime(), time_t(1677840601));
+
+    
QCOMPARE(signatureFields[2]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature2_B_" });
+    QCOMPARE(signatureFields[2]->getSignatureType(), unsigned_signature_field);
+    
QCOMPARE(signatureFields[3]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature3_B_" });
+    QCOMPARE(signatureFields[3]->getSignatureType(), unsigned_signature_field);
+}
+
+void TestSignatureBasics::testSignedRanges()
+{
+    auto signatureFields = doc->getSignatureFields();
+
+    Goffset size0;
+    auto sig0 = signatureFields[0]->getCheckedSignature(&size0);
+    QVERIFY(sig0);
+    auto ranges0 = signatureFields[0]->getSignedRangeBounds();
+    QCOMPARE(ranges0.size(), 4);
+    QCOMPARE(ranges0[0], 0);
+    QCOMPARE(ranges0[1], 24890);
+    QCOMPARE(ranges0[2], 45352);
+    QCOMPARE(ranges0[3], 58529);
+    QVERIFY(ranges0[3] != size0); // signature does not cover all of it
+
+    Goffset size1;
+    auto sig1 = signatureFields[1]->getCheckedSignature(&size1);
+    QVERIFY(sig1);
+    auto ranges1 = signatureFields[1]->getSignedRangeBounds();
+    QCOMPARE(ranges1.size(), 4);
+    QCOMPARE(ranges1[0], 0);
+    QCOMPARE(ranges1[1], 59257);
+    QCOMPARE(ranges1[2], 79651);
+    QCOMPARE(ranges1[3], 92773);
+    QCOMPARE(ranges1[3], size1); // signature does cover all of it
+}
+
+QTEST_GUILESS_MAIN(TestSignatureBasics)
+#include "check_signature_basics.moc"
diff --git a/qt6/tests/CMakeLists.txt b/qt6/tests/CMakeLists.txt
index 90ec00cc..36da5b9f 100644
--- a/qt6/tests/CMakeLists.txt
+++ b/qt6/tests/CMakeLists.txt
@@ -62,6 +62,7 @@ qt6_add_qtest(check_qt6_object check_object.cpp)
 qt6_add_qtest(check_qt6_stroke_opacity check_stroke_opacity.cpp)
 qt6_add_qtest(check_qt6_utf_conversion check_utf_conversion.cpp)
 qt6_add_qtest(check_qt6_outline check_outline.cpp)
+qt6_add_qtest(check_qt6_signature_basics check_signature_basics.cpp)
 if (NOT WIN32)
   qt6_add_qtest(check_qt6_pagelabelinfo check_pagelabelinfo.cpp)
   qt6_add_qtest(check_qt6_strings check_strings.cpp)
diff --git a/qt6/tests/check_signature_basics.cpp 
b/qt6/tests/check_signature_basics.cpp
new file mode 100644
index 00000000..7cdb1c37
--- /dev/null
+++ b/qt6/tests/check_signature_basics.cpp
@@ -0,0 +1,133 @@
+//========================================================================
+//
+// check_signature_basics.cpp
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright 2023 g10 Code GmbH, Author: Sune Stolborg Vuorela 
<s...@vuorela.dk>
+//========================================================================
+
+// Simple tests of reading signatures
+//
+// Note that this does not check the actual validity because
+// that will have an expiry date, and adding time bombs to unit tests is
+// probably not a good idea.
+#include <QtTest/QtTest>
+#include "PDFDoc.h"
+#include "GlobalParams.h"
+#include "SignatureInfo.h"
+#include "config.h"
+
+class TestSignatureBasics : public QObject
+{
+    Q_OBJECT
+public:
+    explicit TestSignatureBasics(QObject *parent = nullptr) : QObject(parent) 
{ }
+
+private:
+    std::unique_ptr<PDFDoc> doc;
+private Q_SLOTS:
+    void initTestCase();
+    void cleanupTestCase();
+    void testSignatureCount();
+    void testSignatureSizes();
+    void testSignerInfo(); // names and stuff
+    void testSignedRanges();
+};
+
+void TestSignatureBasics::initTestCase()
+{
+    globalParams = std::make_unique<GlobalParams>();
+    doc = std::make_unique<PDFDoc>(std::make_unique<GooString>(TESTDATADIR 
"/unittestcases/pdf-signature-sample-2sigs.pdf"));
+    QVERIFY(doc);
+    QVERIFY(doc->isOk());
+}
+void TestSignatureBasics::cleanupTestCase()
+{
+    globalParams.reset();
+}
+
+void TestSignatureBasics::testSignatureCount()
+{
+    QVERIFY(doc);
+    auto signatureFields = doc->getSignatureFields();
+    QCOMPARE(signatureFields.size(), 4);
+    // count active signatures
+    QVERIFY(signatureFields[0]->getSignature());
+    QVERIFY(signatureFields[1]->getSignature());
+    QVERIFY(!signatureFields[2]->getSignature());
+    QVERIFY(!signatureFields[3]->getSignature());
+}
+
+void TestSignatureBasics::testSignatureSizes()
+{
+    auto signatureFields = doc->getSignatureFields();
+    // Note for later. Unpadding a signature on a command line with openssl can
+    // be done just by rewriting after using e.g. pdfsig -dump to extract them
+    // openssl pkcs7 -inform der -in pdf-signature-sample-2sigs.pdf.sig0 
-outform der -out pdf-signature-sample-2sigs.pdf.sig0.unpadded
+    QCOMPARE(signatureFields[0]->getSignature()->getLength(), 10230); // This 
is technically wrong, because the signatures in this document has been padded. 
The correct size is 2340
+    QCOMPARE(signatureFields[1]->getSignature()->getLength(), 10196); // This 
is technically wrong, because the signatures in this document has been padded. 
The correct size is 2340
+}
+
+void TestSignatureBasics::testSignerInfo()
+{
+    auto signatureFields = doc->getSignatureFields();
+    
QCOMPARE(signatureFields[0]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature0_B_" });
+    QCOMPARE(signatureFields[0]->getSignatureType(), ETSI_CAdES_detached);
+    auto siginfo0 = signatureFields[0]->validateSignature(false, false, -1 /* 
now */, false, false);
+#ifdef ENABLE_NSS3
+    QCOMPARE(siginfo0->getSignerName(), std::string { "Koch, Werner" });
+    QCOMPARE(siginfo0->getHashAlgorithm(), HashAlgorithm::Sha256);
+#else
+    QCOMPARE(siginfo0->getSignerName(), std::string {});
+    QCOMPARE(siginfo0->getHashAlgorithm(), HashAlgorithm::Unknown);
+#endif
+    QCOMPARE(siginfo0->getSigningTime(), time_t(1677570911));
+
+    
QCOMPARE(signatureFields[1]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature1_B_" });
+    QCOMPARE(signatureFields[1]->getSignatureType(), ETSI_CAdES_detached);
+    auto siginfo1 = signatureFields[1]->validateSignature(false, false, -1 /* 
now */, false, false);
+#ifdef ENABLE_NSS3
+    QCOMPARE(siginfo1->getSignerName(), std::string { "Koch, Werner" });
+    QCOMPARE(siginfo1->getHashAlgorithm(), HashAlgorithm::Sha256);
+#else
+    QCOMPARE(siginfo1->getSignerName(), std::string {});
+    QCOMPARE(siginfo1->getHashAlgorithm(), HashAlgorithm::Unknown);
+#endif
+    QCOMPARE(siginfo1->getSigningTime(), time_t(1677840601));
+
+    
QCOMPARE(signatureFields[2]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature2_B_" });
+    QCOMPARE(signatureFields[2]->getSignatureType(), unsigned_signature_field);
+    
QCOMPARE(signatureFields[3]->getCreateWidget()->getField()->getFullyQualifiedName()->toStr(),
 std::string { "P2.AnA_Signature3_B_" });
+    QCOMPARE(signatureFields[3]->getSignatureType(), unsigned_signature_field);
+}
+
+void TestSignatureBasics::testSignedRanges()
+{
+    auto signatureFields = doc->getSignatureFields();
+
+    Goffset size0;
+    auto sig0 = signatureFields[0]->getCheckedSignature(&size0);
+    QVERIFY(sig0);
+    auto ranges0 = signatureFields[0]->getSignedRangeBounds();
+    QCOMPARE(ranges0.size(), 4);
+    QCOMPARE(ranges0[0], 0);
+    QCOMPARE(ranges0[1], 24890);
+    QCOMPARE(ranges0[2], 45352);
+    QCOMPARE(ranges0[3], 58529);
+    QVERIFY(ranges0[3] != size0); // signature does not cover all of it
+
+    Goffset size1;
+    auto sig1 = signatureFields[1]->getCheckedSignature(&size1);
+    QVERIFY(sig1);
+    auto ranges1 = signatureFields[1]->getSignedRangeBounds();
+    QCOMPARE(ranges1.size(), 4);
+    QCOMPARE(ranges1[0], 0);
+    QCOMPARE(ranges1[1], 59257);
+    QCOMPARE(ranges1[2], 79651);
+    QCOMPARE(ranges1[3], 92773);
+    QCOMPARE(ranges1[3], size1); // signature does cover all of it
+}
+
+QTEST_GUILESS_MAIN(TestSignatureBasics)
+#include "check_signature_basics.moc"

Reply via email to