1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2020 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_signature.h"
8*3ac0a46fSAndroid Build Coastguard Worker #include "testing/embedder_test.h"
9*3ac0a46fSAndroid Build Coastguard Worker #include "testing/fx_string_testhelpers.h"
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker class FPDFSignatureEmbedderTest : public EmbedderTest {};
12*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetSignatureCount)13*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetSignatureCount) {
14*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
15*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(2, FPDF_GetSignatureCount(document()));
16*3ac0a46fSAndroid Build Coastguard Worker }
17*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetSignatureCountZero)18*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetSignatureCountZero) {
19*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("hello_world.pdf"));
20*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, FPDF_GetSignatureCount(document()));
21*3ac0a46fSAndroid Build Coastguard Worker
22*3ac0a46fSAndroid Build Coastguard Worker // Provide no document.
23*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(-1, FPDF_GetSignatureCount(nullptr));
24*3ac0a46fSAndroid Build Coastguard Worker }
25*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetSignatureObject)26*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetSignatureObject) {
27*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
28*3ac0a46fSAndroid Build Coastguard Worker // Different, non-null signature objects are returned.
29*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature1 = FPDF_GetSignatureObject(document(), 0);
30*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature1);
31*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature2 = FPDF_GetSignatureObject(document(), 1);
32*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature2);
33*3ac0a46fSAndroid Build Coastguard Worker EXPECT_NE(signature1, signature2);
34*3ac0a46fSAndroid Build Coastguard Worker
35*3ac0a46fSAndroid Build Coastguard Worker // Out of bounds.
36*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(FPDF_GetSignatureObject(document(), -1));
37*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(FPDF_GetSignatureObject(document(), 2));
38*3ac0a46fSAndroid Build Coastguard Worker
39*3ac0a46fSAndroid Build Coastguard Worker // Provide no document.
40*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(FPDF_GetSignatureObject(nullptr, 0));
41*3ac0a46fSAndroid Build Coastguard Worker }
42*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetContents)43*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetContents) {
44*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
45*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
46*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
47*3ac0a46fSAndroid Build Coastguard Worker
48*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetContents() positive testing.
49*3ac0a46fSAndroid Build Coastguard Worker unsigned long size = FPDFSignatureObj_GetContents(signature, nullptr, 0);
50*3ac0a46fSAndroid Build Coastguard Worker const uint8_t kExpectedContents[] = {0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48,
51*3ac0a46fSAndroid Build Coastguard Worker 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0,
52*3ac0a46fSAndroid Build Coastguard Worker 0x80, 0x30, 0x80, 0x02, 0x01, 0x01};
53*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedContents), size);
54*3ac0a46fSAndroid Build Coastguard Worker std::vector<char> contents(size);
55*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(size,
56*3ac0a46fSAndroid Build Coastguard Worker FPDFSignatureObj_GetContents(signature, contents.data(), size));
57*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(kExpectedContents, contents.data(), size));
58*3ac0a46fSAndroid Build Coastguard Worker
59*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetContents() negative testing.
60*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetContents(nullptr, nullptr, 0));
61*3ac0a46fSAndroid Build Coastguard Worker
62*3ac0a46fSAndroid Build Coastguard Worker contents.resize(2);
63*3ac0a46fSAndroid Build Coastguard Worker contents[0] = 'x';
64*3ac0a46fSAndroid Build Coastguard Worker contents[1] = '\0';
65*3ac0a46fSAndroid Build Coastguard Worker size =
66*3ac0a46fSAndroid Build Coastguard Worker FPDFSignatureObj_GetContents(signature, contents.data(), contents.size());
67*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedContents), size);
68*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('x', contents[0]);
69*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('\0', contents[1]);
70*3ac0a46fSAndroid Build Coastguard Worker }
71*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetByteRange)72*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetByteRange) {
73*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
74*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
75*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
76*3ac0a46fSAndroid Build Coastguard Worker
77*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetByteRange() positive testing.
78*3ac0a46fSAndroid Build Coastguard Worker unsigned long size = FPDFSignatureObj_GetByteRange(signature, nullptr, 0);
79*3ac0a46fSAndroid Build Coastguard Worker const std::vector<int> kExpectedByteRange{0, 10, 30, 10};
80*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kExpectedByteRange.size(), size);
81*3ac0a46fSAndroid Build Coastguard Worker std::vector<int> byte_range(size);
82*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(size,
83*3ac0a46fSAndroid Build Coastguard Worker FPDFSignatureObj_GetByteRange(signature, byte_range.data(), size));
84*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kExpectedByteRange, byte_range);
85*3ac0a46fSAndroid Build Coastguard Worker
86*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetByteRange() negative testing.
87*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetByteRange(nullptr, nullptr, 0));
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker byte_range.resize(2);
90*3ac0a46fSAndroid Build Coastguard Worker byte_range[0] = 0;
91*3ac0a46fSAndroid Build Coastguard Worker byte_range[1] = 1;
92*3ac0a46fSAndroid Build Coastguard Worker size = FPDFSignatureObj_GetByteRange(signature, byte_range.data(),
93*3ac0a46fSAndroid Build Coastguard Worker byte_range.size());
94*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kExpectedByteRange.size(), size);
95*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, byte_range[0]);
96*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1, byte_range[1]);
97*3ac0a46fSAndroid Build Coastguard Worker }
98*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetSubFilter)99*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetSubFilter) {
100*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
101*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
102*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
103*3ac0a46fSAndroid Build Coastguard Worker
104*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetSubFilter() positive testing.
105*3ac0a46fSAndroid Build Coastguard Worker unsigned long size = FPDFSignatureObj_GetSubFilter(signature, nullptr, 0);
106*3ac0a46fSAndroid Build Coastguard Worker const char kExpectedSubFilter[] = "ETSI.CAdES.detached";
107*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedSubFilter), size);
108*3ac0a46fSAndroid Build Coastguard Worker std::vector<char> sub_filter(size);
109*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(size,
110*3ac0a46fSAndroid Build Coastguard Worker FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(), size));
111*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(kExpectedSubFilter, sub_filter.data(), size));
112*3ac0a46fSAndroid Build Coastguard Worker
113*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetSubFilter() negative testing.
114*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(nullptr, nullptr, 0));
115*3ac0a46fSAndroid Build Coastguard Worker
116*3ac0a46fSAndroid Build Coastguard Worker sub_filter.resize(2);
117*3ac0a46fSAndroid Build Coastguard Worker sub_filter[0] = 'x';
118*3ac0a46fSAndroid Build Coastguard Worker sub_filter[1] = '\0';
119*3ac0a46fSAndroid Build Coastguard Worker size = FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(),
120*3ac0a46fSAndroid Build Coastguard Worker sub_filter.size());
121*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedSubFilter), size);
122*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('x', sub_filter[0]);
123*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('\0', sub_filter[1]);
124*3ac0a46fSAndroid Build Coastguard Worker }
125*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetSubFilterNoKeyExists)126*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetSubFilterNoKeyExists) {
127*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("signature_no_sub_filter.pdf"));
128*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
129*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
130*3ac0a46fSAndroid Build Coastguard Worker
131*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetSubFilter() negative testing: no SubFilter
132*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(signature, nullptr, 0));
133*3ac0a46fSAndroid Build Coastguard Worker }
134*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetReason)135*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetReason) {
136*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("signature_reason.pdf"));
137*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
138*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
139*3ac0a46fSAndroid Build Coastguard Worker
140*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetReason() positive testing.
141*3ac0a46fSAndroid Build Coastguard Worker constexpr char kReason[] = "test reason";
142*3ac0a46fSAndroid Build Coastguard Worker // Return value includes the terminating NUL that is provided.
143*3ac0a46fSAndroid Build Coastguard Worker constexpr unsigned long kReasonUTF16Size = std::size(kReason) * 2;
144*3ac0a46fSAndroid Build Coastguard Worker constexpr wchar_t kReasonWide[] = L"test reason";
145*3ac0a46fSAndroid Build Coastguard Worker unsigned long size = FPDFSignatureObj_GetReason(signature, nullptr, 0);
146*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kReasonUTF16Size, size);
147*3ac0a46fSAndroid Build Coastguard Worker
148*3ac0a46fSAndroid Build Coastguard Worker std::vector<unsigned short> buffer(size);
149*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(size, FPDFSignatureObj_GetReason(signature, buffer.data(), size));
150*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kReasonWide, GetPlatformWString(buffer.data()));
151*3ac0a46fSAndroid Build Coastguard Worker
152*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetReason() negative testing.
153*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetReason(nullptr, nullptr, 0));
154*3ac0a46fSAndroid Build Coastguard Worker
155*3ac0a46fSAndroid Build Coastguard Worker // Buffer is too small, ensure it's not modified.
156*3ac0a46fSAndroid Build Coastguard Worker buffer.resize(2);
157*3ac0a46fSAndroid Build Coastguard Worker buffer[0] = 'x';
158*3ac0a46fSAndroid Build Coastguard Worker buffer[1] = '\0';
159*3ac0a46fSAndroid Build Coastguard Worker size = FPDFSignatureObj_GetReason(signature, buffer.data(), buffer.size());
160*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(kReasonUTF16Size, size);
161*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('x', buffer[0]);
162*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('\0', buffer[1]);
163*3ac0a46fSAndroid Build Coastguard Worker }
164*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetTime)165*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetTime) {
166*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
167*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
168*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(signature);
169*3ac0a46fSAndroid Build Coastguard Worker
170*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetTime() positive testing.
171*3ac0a46fSAndroid Build Coastguard Worker unsigned long size = FPDFSignatureObj_GetTime(signature, nullptr, 0);
172*3ac0a46fSAndroid Build Coastguard Worker const char kExpectedTime[] = "D:20200624093114+02'00'";
173*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedTime), size);
174*3ac0a46fSAndroid Build Coastguard Worker std::vector<char> time_buffer(size);
175*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(size,
176*3ac0a46fSAndroid Build Coastguard Worker FPDFSignatureObj_GetTime(signature, time_buffer.data(), size));
177*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(kExpectedTime, time_buffer.data(), size));
178*3ac0a46fSAndroid Build Coastguard Worker
179*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetTime() negative testing.
180*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(0U, FPDFSignatureObj_GetTime(nullptr, nullptr, 0));
181*3ac0a46fSAndroid Build Coastguard Worker
182*3ac0a46fSAndroid Build Coastguard Worker time_buffer.resize(2);
183*3ac0a46fSAndroid Build Coastguard Worker time_buffer[0] = 'x';
184*3ac0a46fSAndroid Build Coastguard Worker time_buffer[1] = '\0';
185*3ac0a46fSAndroid Build Coastguard Worker size = FPDFSignatureObj_GetTime(signature, time_buffer.data(),
186*3ac0a46fSAndroid Build Coastguard Worker time_buffer.size());
187*3ac0a46fSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kExpectedTime), size);
188*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('x', time_buffer[0]);
189*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ('\0', time_buffer[1]);
190*3ac0a46fSAndroid Build Coastguard Worker }
191*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(FPDFSignatureEmbedderTest,GetDocMDPPermission)192*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFSignatureEmbedderTest, GetDocMDPPermission) {
193*3ac0a46fSAndroid Build Coastguard Worker ASSERT_TRUE(OpenDocument("docmdp.pdf"));
194*3ac0a46fSAndroid Build Coastguard Worker FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
195*3ac0a46fSAndroid Build Coastguard Worker ASSERT_NE(nullptr, signature);
196*3ac0a46fSAndroid Build Coastguard Worker
197*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetDocMDPPermission() positive testing.
198*3ac0a46fSAndroid Build Coastguard Worker unsigned int permission = FPDFSignatureObj_GetDocMDPPermission(signature);
199*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1U, permission);
200*3ac0a46fSAndroid Build Coastguard Worker
201*3ac0a46fSAndroid Build Coastguard Worker // FPDFSignatureObj_GetDocMDPPermission() negative testing.
202*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0U, FPDFSignatureObj_GetDocMDPPermission(nullptr));
203*3ac0a46fSAndroid Build Coastguard Worker }
204