@@ -56,16 +56,20 @@ This file is part of the iText (R) project.
56
56
import com .itextpdf .signatures .BouncyCastleDigest ;
57
57
import com .itextpdf .signatures .DigestAlgorithms ;
58
58
import com .itextpdf .signatures .IExternalSignature ;
59
+ import com .itextpdf .signatures .PdfPKCS7 ;
59
60
import com .itextpdf .signatures .PdfSignatureAppearance ;
60
61
import com .itextpdf .signatures .PdfSigner ;
61
62
import com .itextpdf .signatures .PrivateKeySignature ;
63
+ import com .itextpdf .signatures .SignatureUtil ;
62
64
import com .itextpdf .test .signutils .Pkcs12FileHelper ;
63
65
import com .itextpdf .test .ExtendedITextTest ;
64
66
import com .itextpdf .test .annotations .type .IntegrationTest ;
67
+
65
68
import org .bouncycastle .jce .provider .BouncyCastleProvider ;
66
69
import org .junit .Assert ;
67
70
import org .junit .Before ;
68
71
import org .junit .BeforeClass ;
72
+ import org .junit .Rule ;
69
73
import org .junit .Test ;
70
74
import org .junit .experimental .categories .Category ;
71
75
@@ -83,6 +87,7 @@ This file is part of the iText (R) project.
83
87
import java .util .HashMap ;
84
88
import java .util .List ;
85
89
import java .util .Map ;
90
+ import org .junit .rules .ExpectedException ;
86
91
87
92
@ Category (IntegrationTest .class )
88
93
public class PdfSignatureAppearanceTest extends ExtendedITextTest {
@@ -95,6 +100,9 @@ public class PdfSignatureAppearanceTest extends ExtendedITextTest {
95
100
private Certificate [] chain ;
96
101
private PrivateKey pk ;
97
102
103
+ @ Rule
104
+ public ExpectedException junitExpectedException = ExpectedException .none ();
105
+
98
106
@ BeforeClass
99
107
public static void before () {
100
108
Security .addProvider (new BouncyCastleProvider ());
@@ -242,6 +250,108 @@ public void signaturesOnRotatedPages() throws IOException, GeneralSecurityExcept
242
250
Assert .assertEquals ("" , assertionResults .toString ());
243
251
}
244
252
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
+
245
355
private void testSignatureOnRotatedPage (int pageNum , PdfSignatureAppearance .RenderingMode renderingMode , StringBuilder assertionResults ) throws IOException , GeneralSecurityException , InterruptedException {
246
356
String fileName = "signaturesOnRotatedPages" + pageNum + "_mode_" + renderingMode .name () + ".pdf" ;
247
357
String src = sourceFolder + "documentWithRotatedPages.pdf" ;
0 commit comments