Skip to content

Commit 3106077

Browse files
author
Kate Ivanova
committed
Add integration test for handling signatures with not merged widgets
DEVSIX-5187
1 parent f40cfbe commit 3106077

File tree

6 files changed

+110
-0
lines changed

6 files changed

+110
-0
lines changed

sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,20 @@ This file is part of the iText (R) project.
5656
import com.itextpdf.signatures.BouncyCastleDigest;
5757
import com.itextpdf.signatures.DigestAlgorithms;
5858
import com.itextpdf.signatures.IExternalSignature;
59+
import com.itextpdf.signatures.PdfPKCS7;
5960
import com.itextpdf.signatures.PdfSignatureAppearance;
6061
import com.itextpdf.signatures.PdfSigner;
6162
import com.itextpdf.signatures.PrivateKeySignature;
63+
import com.itextpdf.signatures.SignatureUtil;
6264
import com.itextpdf.test.signutils.Pkcs12FileHelper;
6365
import com.itextpdf.test.ExtendedITextTest;
6466
import com.itextpdf.test.annotations.type.IntegrationTest;
67+
6568
import org.bouncycastle.jce.provider.BouncyCastleProvider;
6669
import org.junit.Assert;
6770
import org.junit.Before;
6871
import org.junit.BeforeClass;
72+
import org.junit.Rule;
6973
import org.junit.Test;
7074
import org.junit.experimental.categories.Category;
7175

@@ -83,6 +87,7 @@ This file is part of the iText (R) project.
8387
import java.util.HashMap;
8488
import java.util.List;
8589
import java.util.Map;
90+
import org.junit.rules.ExpectedException;
8691

8792
@Category(IntegrationTest.class)
8893
public class PdfSignatureAppearanceTest extends ExtendedITextTest {
@@ -95,6 +100,9 @@ public class PdfSignatureAppearanceTest extends ExtendedITextTest {
95100
private Certificate[] chain;
96101
private PrivateKey pk;
97102

103+
@Rule
104+
public ExpectedException junitExpectedException = ExpectedException.none();
105+
98106
@BeforeClass
99107
public static void before() {
100108
Security.addProvider(new BouncyCastleProvider());
@@ -242,6 +250,108 @@ public void signaturesOnRotatedPages() throws IOException, GeneralSecurityExcept
242250
Assert.assertEquals("", assertionResults.toString());
243251
}
244252

253+
@Test
254+
public void signatureFieldNotMergedWithWidgetTest() throws IOException, GeneralSecurityException {
255+
try (PdfDocument outputDoc = new PdfDocument(new PdfReader(
256+
sourceFolder + "signatureFieldNotMergedWithWidget.pdf"))) {
257+
258+
SignatureUtil sigUtil = new SignatureUtil(outputDoc);
259+
PdfPKCS7 signatureData = sigUtil.readSignatureData("Signature1");
260+
Assert.assertTrue(signatureData.verifySignatureIntegrityAndAuthenticity());
261+
}
262+
}
263+
264+
@Test
265+
// TODO: DEVSIX-5162 (the signature is expected to have auto-generated appearance, but now it's empty)
266+
public void signExistingNotMergedFieldNotReusedAPTest() throws GeneralSecurityException,
267+
IOException, InterruptedException {
268+
// Field is not merged with widget and has /P key
269+
String src = sourceFolder + "emptyFieldNotMerged.pdf";
270+
String fileName = "signExistingNotMergedFieldNotReusedAP.pdf";
271+
String dest = destinationFolder + fileName;
272+
273+
PdfReader reader = new PdfReader(src);
274+
275+
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties());
276+
signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED);
277+
278+
signer.getSignatureAppearance()
279+
.setLayer2Text("Verified and signed by me.")
280+
.setReason("Test 1")
281+
.setLocation("TestCity")
282+
.setReuseAppearance(false);
283+
signer.setFieldName("Signature1");
284+
285+
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256,
286+
BouncyCastleProvider.PROVIDER_NAME);
287+
signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null,
288+
0, PdfSigner.CryptoStandard.CADES);
289+
290+
Assert.assertNull(new CompareTool().compareVisually(
291+
dest, sourceFolder + "cmp_" + fileName, destinationFolder, "diff_"));
292+
}
293+
294+
@Test
295+
// TODO: DEVSIX-5162 (signature appearance expected to be updated (reused appearance will be used as a background))
296+
public void signExistingNotMergedFieldReusedAPTest() throws GeneralSecurityException,
297+
IOException, InterruptedException {
298+
// Field is not merged with widget and has /P key
299+
String src = sourceFolder + "emptyFieldNotMerged.pdf";
300+
String fileName = "signExistingNotMergedFieldReusedAP.pdf";
301+
String dest = destinationFolder + fileName;
302+
303+
PdfReader reader = new PdfReader(src);
304+
305+
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties());
306+
signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED);
307+
308+
signer.getSignatureAppearance()
309+
.setLayer2Text("Verified and signed by me.")
310+
.setReason("Test 1")
311+
.setLocation("TestCity")
312+
.setReuseAppearance(true);
313+
signer.setFieldName("Signature1");
314+
315+
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256,
316+
BouncyCastleProvider.PROVIDER_NAME);
317+
signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null,
318+
0, PdfSigner.CryptoStandard.CADES);
319+
320+
Assert.assertNull(new CompareTool().compareVisually(
321+
dest, sourceFolder + "cmp_" + fileName, destinationFolder, "diff_"));
322+
}
323+
324+
@Test
325+
// TODO: DEVSIX-5162 (remove expected exception after fix)
326+
public void signExistingNotMergedFieldReusedAPEntryNDicTest() throws GeneralSecurityException,
327+
IOException, InterruptedException {
328+
// Field is not merged with widget and has /P key
329+
String src = sourceFolder + "emptyFieldNotMergedEntryNDict.pdf";
330+
String fileName = "signExistingNotMergedFieldReusedAPEntryNDic.pdf";
331+
String dest = destinationFolder + fileName;
332+
333+
PdfReader reader = new PdfReader(src);
334+
335+
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties());
336+
signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED);
337+
338+
junitExpectedException.expect(NullPointerException.class);
339+
signer.getSignatureAppearance()
340+
.setLayer2Text("Verified and signed by me.")
341+
.setReason("Test 1")
342+
.setLocation("TestCity")
343+
.setReuseAppearance(true);
344+
signer.setFieldName("Signature1");
345+
346+
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256,
347+
BouncyCastleProvider.PROVIDER_NAME);
348+
signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null,
349+
0, PdfSigner.CryptoStandard.CADES);
350+
351+
Assert.assertNull(new CompareTool().compareVisually(
352+
dest, sourceFolder + "cmp_" + fileName, destinationFolder, "diff_"));
353+
}
354+
245355
private void testSignatureOnRotatedPage(int pageNum, PdfSignatureAppearance.RenderingMode renderingMode, StringBuilder assertionResults) throws IOException, GeneralSecurityException, InterruptedException {
246356
String fileName = "signaturesOnRotatedPages" + pageNum + "_mode_" + renderingMode.name() + ".pdf";
247357
String src = sourceFolder + "documentWithRotatedPages.pdf";

0 commit comments

Comments
 (0)