| // Copyright 2020 The PDFium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <vector> | |
| #include "public/fpdf_signature.h" | |
| #include "testing/embedder_test.h" | |
| #include "testing/fx_string_testhelpers.h" | |
| class FPDFSignatureEmbedderTest : public EmbedderTest {}; | |
| TEST_F(FPDFSignatureEmbedderTest, GetSignatureCount) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| EXPECT_EQ(2, FPDF_GetSignatureCount(document())); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetSignatureCountZero) { | |
| ASSERT_TRUE(OpenDocument("hello_world.pdf")); | |
| EXPECT_EQ(0, FPDF_GetSignatureCount(document())); | |
| // Provide no document. | |
| EXPECT_EQ(-1, FPDF_GetSignatureCount(nullptr)); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetSignatureObject) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| // Different, non-null signature objects are returned. | |
| FPDF_SIGNATURE signature1 = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature1); | |
| FPDF_SIGNATURE signature2 = FPDF_GetSignatureObject(document(), 1); | |
| EXPECT_TRUE(signature2); | |
| EXPECT_NE(signature1, signature2); | |
| // Out of bounds. | |
| EXPECT_FALSE(FPDF_GetSignatureObject(document(), -1)); | |
| EXPECT_FALSE(FPDF_GetSignatureObject(document(), 2)); | |
| // Provide no document. | |
| EXPECT_FALSE(FPDF_GetSignatureObject(nullptr, 0)); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetContents) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetContents() positive testing. | |
| unsigned long size = FPDFSignatureObj_GetContents(signature, nullptr, 0); | |
| const uint8_t kExpectedContents[] = {0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48, | |
| 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0, | |
| 0x80, 0x30, 0x80, 0x02, 0x01, 0x01}; | |
| ASSERT_EQ(sizeof(kExpectedContents), size); | |
| std::vector<char> contents(size); | |
| ASSERT_EQ(size, | |
| FPDFSignatureObj_GetContents(signature, contents.data(), size)); | |
| ASSERT_EQ(0, memcmp(kExpectedContents, contents.data(), size)); | |
| // FPDFSignatureObj_GetContents() negative testing. | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetContents(nullptr, nullptr, 0)); | |
| contents.resize(2); | |
| contents[0] = 'x'; | |
| contents[1] = '\0'; | |
| size = | |
| FPDFSignatureObj_GetContents(signature, contents.data(), contents.size()); | |
| ASSERT_EQ(sizeof(kExpectedContents), size); | |
| EXPECT_EQ('x', contents[0]); | |
| EXPECT_EQ('\0', contents[1]); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetByteRange) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetByteRange() positive testing. | |
| unsigned long size = FPDFSignatureObj_GetByteRange(signature, nullptr, 0); | |
| const std::vector<int> kExpectedByteRange{0, 10, 30, 10}; | |
| ASSERT_EQ(kExpectedByteRange.size(), size); | |
| std::vector<int> byte_range(size); | |
| ASSERT_EQ(size, | |
| FPDFSignatureObj_GetByteRange(signature, byte_range.data(), size)); | |
| ASSERT_EQ(kExpectedByteRange, byte_range); | |
| // FPDFSignatureObj_GetByteRange() negative testing. | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetByteRange(nullptr, nullptr, 0)); | |
| byte_range.resize(2); | |
| byte_range[0] = 0; | |
| byte_range[1] = 1; | |
| size = FPDFSignatureObj_GetByteRange(signature, byte_range.data(), | |
| byte_range.size()); | |
| ASSERT_EQ(kExpectedByteRange.size(), size); | |
| EXPECT_EQ(0, byte_range[0]); | |
| EXPECT_EQ(1, byte_range[1]); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetSubFilter) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetSubFilter() positive testing. | |
| unsigned long size = FPDFSignatureObj_GetSubFilter(signature, nullptr, 0); | |
| const char kExpectedSubFilter[] = "ETSI.CAdES.detached"; | |
| ASSERT_EQ(sizeof(kExpectedSubFilter), size); | |
| std::vector<char> sub_filter(size); | |
| ASSERT_EQ(size, | |
| FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(), size)); | |
| ASSERT_EQ(0, memcmp(kExpectedSubFilter, sub_filter.data(), size)); | |
| // FPDFSignatureObj_GetSubFilter() negative testing. | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(nullptr, nullptr, 0)); | |
| sub_filter.resize(2); | |
| sub_filter[0] = 'x'; | |
| sub_filter[1] = '\0'; | |
| size = FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(), | |
| sub_filter.size()); | |
| ASSERT_EQ(sizeof(kExpectedSubFilter), size); | |
| EXPECT_EQ('x', sub_filter[0]); | |
| EXPECT_EQ('\0', sub_filter[1]); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetSubFilterNoKeyExists) { | |
| ASSERT_TRUE(OpenDocument("signature_no_sub_filter.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetSubFilter() negative testing: no SubFilter | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(signature, nullptr, 0)); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetReason) { | |
| ASSERT_TRUE(OpenDocument("signature_reason.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetReason() positive testing. | |
| constexpr char kReason[] = "test reason"; | |
| // Return value includes the terminating NUL that is provided. | |
| constexpr unsigned long kReasonUTF16Size = std::size(kReason) * 2; | |
| constexpr wchar_t kReasonWide[] = L"test reason"; | |
| unsigned long size = FPDFSignatureObj_GetReason(signature, nullptr, 0); | |
| ASSERT_EQ(kReasonUTF16Size, size); | |
| std::vector<unsigned short> buffer(size); | |
| ASSERT_EQ(size, FPDFSignatureObj_GetReason(signature, buffer.data(), size)); | |
| ASSERT_EQ(kReasonWide, GetPlatformWString(buffer.data())); | |
| // FPDFSignatureObj_GetReason() negative testing. | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetReason(nullptr, nullptr, 0)); | |
| // Buffer is too small, ensure it's not modified. | |
| buffer.resize(2); | |
| buffer[0] = 'x'; | |
| buffer[1] = '\0'; | |
| size = FPDFSignatureObj_GetReason(signature, buffer.data(), buffer.size()); | |
| ASSERT_EQ(kReasonUTF16Size, size); | |
| EXPECT_EQ('x', buffer[0]); | |
| EXPECT_EQ('\0', buffer[1]); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetTime) { | |
| ASSERT_TRUE(OpenDocument("two_signatures.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| EXPECT_TRUE(signature); | |
| // FPDFSignatureObj_GetTime() positive testing. | |
| unsigned long size = FPDFSignatureObj_GetTime(signature, nullptr, 0); | |
| const char kExpectedTime[] = "D:20200624093114+02'00'"; | |
| ASSERT_EQ(sizeof(kExpectedTime), size); | |
| std::vector<char> time_buffer(size); | |
| ASSERT_EQ(size, | |
| FPDFSignatureObj_GetTime(signature, time_buffer.data(), size)); | |
| ASSERT_EQ(0, memcmp(kExpectedTime, time_buffer.data(), size)); | |
| // FPDFSignatureObj_GetTime() negative testing. | |
| ASSERT_EQ(0U, FPDFSignatureObj_GetTime(nullptr, nullptr, 0)); | |
| time_buffer.resize(2); | |
| time_buffer[0] = 'x'; | |
| time_buffer[1] = '\0'; | |
| size = FPDFSignatureObj_GetTime(signature, time_buffer.data(), | |
| time_buffer.size()); | |
| ASSERT_EQ(sizeof(kExpectedTime), size); | |
| EXPECT_EQ('x', time_buffer[0]); | |
| EXPECT_EQ('\0', time_buffer[1]); | |
| } | |
| TEST_F(FPDFSignatureEmbedderTest, GetDocMDPPermission) { | |
| ASSERT_TRUE(OpenDocument("docmdp.pdf")); | |
| FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0); | |
| ASSERT_NE(nullptr, signature); | |
| // FPDFSignatureObj_GetDocMDPPermission() positive testing. | |
| unsigned int permission = FPDFSignatureObj_GetDocMDPPermission(signature); | |
| EXPECT_EQ(1U, permission); | |
| // FPDFSignatureObj_GetDocMDPPermission() negative testing. | |
| EXPECT_EQ(0U, FPDFSignatureObj_GetDocMDPPermission(nullptr)); | |
| } |