From 610bd4b16fa6528de7859e8df050fea6f629fb2a Mon Sep 17 00:00:00 2001 From: Vladimir Osipchuk Date: Tue, 20 Nov 2018 16:48:44 +0300 Subject: [PATCH] Check whether a signature indeed covers a whole document. Add some tests. Introduce ContentsChecker. Refactor SignatureUtil. DEVSIX-2422 --- .../com/itextpdf/kernel/pdf/PdfReader.java | 52 ++--- .../itextpdf/signatures/SignatureUtil.java | 179 ++++++++++++++---- .../signatures/SignatureUtilTest.java | 89 +++++++++ .../bytesAreCoveredTest01.pdf | Bin 0 -> 18989 bytes .../bytesAreCoveredTest02.pdf | Bin 0 -> 19419 bytes .../bytesAreNotCoveredTest01.pdf | Bin 0 -> 18989 bytes .../firstBytesNotCoveredTest01.pdf | Bin 0 -> 18989 bytes .../lastBytesNotCoveredTest01.pdf | Bin 0 -> 18989 bytes .../lastBytesNotCoveredTest02.pdf | Bin 0 -> 18989 bytes .../notIndirectSigDictionaryTest.pdf | Bin 0 -> 18954 bytes .../spacesBeforeContentsTest01.pdf | Bin 0 -> 18989 bytes .../spacesBeforeContentsTest02.pdf | Bin 0 -> 18989 bytes .../SignatureUtilTest/twoContentsTest01.pdf | Bin 0 -> 18989 bytes 13 files changed, 262 insertions(+), 58 deletions(-) create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreCoveredTest01.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreCoveredTest02.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreNotCoveredTest01.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/firstBytesNotCoveredTest01.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/lastBytesNotCoveredTest01.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/lastBytesNotCoveredTest02.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/notIndirectSigDictionaryTest.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/spacesBeforeContentsTest01.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/spacesBeforeContentsTest02.pdf create mode 100644 sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/twoContentsTest01.pdf diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java index ad40a1321e..03e7bc8b72 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java @@ -607,6 +607,33 @@ protected PdfObject readObject(boolean readAsDirect) throws IOException { return readObject(readAsDirect, false); } + protected PdfObject readReference(boolean readAsDirect) { + int num = tokens.getObjNr(); + PdfXrefTable table = pdfDocument.getXref(); + PdfIndirectReference reference = table.get(num); + if (reference != null) { + if (reference.isFree()) { + Logger logger = LoggerFactory.getLogger(PdfReader.class); + logger.warn(MessageFormatUtil.format(LogMessageConstant.INVALID_INDIRECT_REFERENCE, tokens.getObjNr(), tokens.getGenNr())); + return createPdfNullInstance(readAsDirect); + } + if (reference.getGenNumber() != tokens.getGenNr()) { + if (fixedXref) { + Logger logger = LoggerFactory.getLogger(PdfReader.class); + logger.warn(MessageFormatUtil.format(LogMessageConstant.INVALID_INDIRECT_REFERENCE, tokens.getObjNr(), tokens.getGenNr())); + return createPdfNullInstance(readAsDirect); + } else { + throw new PdfException(PdfException.InvalidIndirectReference1, + MessageFormatUtil.format("{0} {1} R", reference.getObjNumber(), reference.getGenNumber())); + } + } + } else { + reference = table.add((PdfIndirectReference) new PdfIndirectReference(pdfDocument, + num, tokens.getGenNr(), 0).setState(PdfObject.READING)); + } + return reference; + } + protected PdfObject readObject(boolean readAsDirect, boolean objStm) throws IOException { tokens.nextValidToken(); PdfTokenizer.TokenType type = tokens.getTokenType(); @@ -650,30 +677,7 @@ protected PdfObject readObject(boolean readAsDirect, boolean objStm) throws IOEx case Name: return readPdfName(readAsDirect); case Ref: - int num = tokens.getObjNr(); - PdfXrefTable table = pdfDocument.getXref(); - PdfIndirectReference reference = table.get(num); - if (reference != null) { - if (reference.isFree()) { - Logger logger = LoggerFactory.getLogger(PdfReader.class); - logger.warn(MessageFormatUtil.format(LogMessageConstant.INVALID_INDIRECT_REFERENCE, tokens.getObjNr(), tokens.getGenNr())); - return createPdfNullInstance(readAsDirect); - } - if (reference.getGenNumber() != tokens.getGenNr()) { - if (fixedXref) { - Logger logger = LoggerFactory.getLogger(PdfReader.class); - logger.warn(MessageFormatUtil.format(LogMessageConstant.INVALID_INDIRECT_REFERENCE, tokens.getObjNr(), tokens.getGenNr())); - return createPdfNullInstance(readAsDirect); - } else { - throw new PdfException(PdfException.InvalidIndirectReference1, - MessageFormatUtil.format("{0} {1} R", reference.getObjNumber(), reference.getGenNumber())); - } - } - } else { - reference = table.add((PdfIndirectReference) new PdfIndirectReference(pdfDocument, - num, tokens.getGenNr(), 0).setState(PdfObject.READING)); - } - return reference; + return readReference(readAsDirect); case EndOfFile: throw new PdfException(PdfException.UnexpectedEndOfFile); default: diff --git a/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java b/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java index 03136a3572..2ed17879e4 100644 --- a/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java +++ b/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java @@ -46,6 +46,8 @@ This file is part of the iText (R) project. import com.itextpdf.forms.PdfAcroForm; import com.itextpdf.forms.fields.PdfFormField; import com.itextpdf.io.font.PdfEncodings; +import com.itextpdf.io.source.IRandomAccessSource; +import com.itextpdf.io.source.PdfTokenizer; import com.itextpdf.io.source.RASInputStream; import com.itextpdf.io.source.RandomAccessFileOrArray; import com.itextpdf.io.source.RandomAccessSourceFactory; @@ -56,6 +58,9 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfNull; +import com.itextpdf.kernel.pdf.PdfObject; +import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfString; import java.io.IOException; @@ -80,6 +85,24 @@ public class SignatureUtil { private List orderedSignatureNames; private int totalRevisions; + /** + * Converts a {@link com.itextpdf.kernel.pdf.PdfArray} to an array of longs + * + * @param pdfArray PdfArray to be converted + * @return long[] containing the PdfArray values + * @deprecated Will be removed in 7.2. Use {@link PdfArray#toLongArray()} instead + */ + @Deprecated + public static long[] asLongArray(PdfArray pdfArray) { + long[] rslt = new long[pdfArray.size()]; + + for (int k = 0; k < rslt.length; ++k) { + rslt[k] = pdfArray.getAsNumber(k).longValue(); + } + + return rslt; + } + /** * Creates a SignatureUtil instance. Sets the acroForm field to the acroForm in the PdfDocument. * iText will create a new AcroForm if the PdfDocument doesn't contain one. @@ -107,7 +130,7 @@ public PdfPKCS7 verifySignature(String name) { * Verifies a signature. Further verification can be done on the returned * {@link PdfPKCS7} object. * - * @param name the signature field name + * @param name the signature field name * @param provider the provider or null for the default provider * @return PdfPKCS7 object to continue the verification */ @@ -124,8 +147,7 @@ public PdfPKCS7 verifySignature(String name, String provider) { if (cert == null) cert = signature.getPdfObject().getAsArray(PdfName.Cert).getAsString(0); pk = new PdfPKCS7(PdfEncodings.convertToBytes(contents.getValue(), null), cert.getValueBytes(), provider); - } - else + } else pk = new PdfPKCS7(PdfEncodings.convertToBytes(contents.getValue(), null), sub, provider); updateByteRange(pk, signature); PdfString date = signature.getDate(); @@ -140,8 +162,7 @@ public PdfPKCS7 verifySignature(String name, String provider) { if (location != null) pk.setLocation(location); return pk; - } - catch (Exception e) { + } catch (Exception e) { throw new PdfException(e); } } @@ -179,8 +200,7 @@ private void updateByteRange(PdfPKCS7 pkcs7, PdfSignature signature) { while ((rd = rg.read(buf, 0, buf.length)) > 0) { pkcs7.update(buf, 0, rd); } - } - catch (Exception e) { + } catch (Exception e) { throw new PdfException(e); } finally { try { @@ -234,13 +254,12 @@ public int getTotalRevisions() { return totalRevisions; } - public int getRevision(String field) { getSignatureNames(); field = getTranslatedFieldName(field); if (!sigNames.containsKey(field)) return 0; - return sigNames.get(field)[1]; + return sigNames.get(field)[1]; } public String getTranslatedFieldName(String name) { @@ -269,7 +288,7 @@ public InputStream extractRevision(String field) throws IOException { } /** - * Checks if the signature covers the entire document or just part of it. + * Checks if the signature covers the entire document (except for signature's Contents) or just a part of it. * * @param name the signature field name * @return true if the signature covers the entire document, false if it doesn't @@ -279,7 +298,8 @@ public boolean signatureCoversWholeDocument(String name) { if (!sigNames.containsKey(name)) return false; try { - return sigNames.get(name)[0] == document.getReader().getFileLength(); + ContentsChecker signatureReader = new ContentsChecker(document.getReader().getSafeFile().createSourceView()); + return signatureReader.checkWhetherSignatureCoversWholeDocument(acroForm.getField(name)); } catch (IOException e) { throw new PdfException(e); } @@ -295,24 +315,6 @@ public boolean doesSignatureFieldExist(String name) { return getBlankSignatureNames().contains(name) || getSignatureNames().contains(name); } - /** - * Converts a {@link com.itextpdf.kernel.pdf.PdfArray} to an array of longs - * - * @param pdfArray PdfArray to be converted - * @return long[] containing the PdfArray values - * @deprecated Will be removed in 7.2. Use {@link PdfArray#toLongArray()} instead - */ - @Deprecated - public static long[] asLongArray(PdfArray pdfArray) { - long[] rslt = new long[pdfArray.size()]; - - for (int k = 0; k < rslt.length; ++k) { - rslt[k] = pdfArray.getAsNumber(k).longValue(); - } - - return rslt; - } - private void populateSignatureNames() { if (acroForm == null) { return; @@ -345,7 +347,7 @@ private void populateSignatureNames() { Collections.sort(sorter, new SorterComparator()); if (sorter.size() > 0) { try { - if (((int[])sorter.get(sorter.size() - 1)[1])[0] == document.getReader().getFileLength()) + if (((int[]) sorter.get(sorter.size() - 1)[1])[0] == document.getReader().getFileLength()) totalRevisions = sorter.size(); else totalRevisions = sorter.size() + 1; @@ -354,8 +356,8 @@ private void populateSignatureNames() { } for (int k = 0; k < sorter.size(); ++k) { Object[] objs = sorter.get(k); - String name = (String)objs[0]; - int[] p = (int[])objs[1]; + String name = (String) objs[0]; + int[] p = (int[]) objs[1]; p[1] = k + 1; sigNames.put(name, p); orderedSignatureNames.add(name); @@ -366,9 +368,118 @@ private void populateSignatureNames() { private static class SorterComparator implements Comparator { @Override public int compare(Object[] o1, Object[] o2) { - int n1 = ((int[])o1[1])[0]; - int n2 = ((int[])o2[1])[0]; + int n1 = ((int[]) o1[1])[0]; + int n2 = ((int[]) o2[1])[0]; return n1 - n2; } } + + private static class ContentsChecker extends PdfReader { + + private long contentsStart; + private long contentsEnd; + + private int currentLevel = 0; + private int contentsLevel = 1; + private boolean searchInV = true; + + private boolean rangeIsCorrect = false; + + + public ContentsChecker(IRandomAccessSource byteSource) throws IOException { + super(byteSource, null); + } + + public boolean checkWhetherSignatureCoversWholeDocument(PdfFormField signatureField) { + rangeIsCorrect = false; + PdfDictionary signature = (PdfDictionary) signatureField.getValue(); + int[] byteRange = ((PdfArray) signature.get(PdfName.ByteRange)).toIntArray(); + try { + if (4 != byteRange.length || 0 != byteRange[0] || tokens.getSafeFile().length() != byteRange[2] + byteRange[3]) { + return false; + } + } catch (IOException e) { + // That's not expected because if the signature is invalid, it should have already failed + return false; + } + + contentsStart = byteRange[1]; + contentsEnd = byteRange[2]; + + long signatureOffset; + if (null != signature.getIndirectReference()) { + signatureOffset = signature.getIndirectReference().getOffset(); + searchInV = true; + } else { + signatureOffset = signatureField.getPdfObject().getIndirectReference().getOffset(); + searchInV = false; + contentsLevel++; + } + + try { + tokens.seek(signatureOffset); + tokens.nextValidToken(); + readObject(false, false); + } catch (IOException e) { + // That's not expected because if the signature is invalid, it should have already failed + return false; + } + + return rangeIsCorrect; + } + + @Override + // The method copies the logic of PdfReader's method. + // Only Contents related checks have been introduced. + protected PdfDictionary readDictionary(boolean objStm) throws IOException { + currentLevel++; + PdfDictionary dic = new PdfDictionary(); + while (!rangeIsCorrect) { + tokens.nextValidToken(); + if (tokens.getTokenType() == PdfTokenizer.TokenType.EndDic) { + currentLevel--; + break; + } + if (tokens.getTokenType() != PdfTokenizer.TokenType.Name) { + tokens.throwError(PdfException.DictionaryKey1IsNotAName, tokens.getStringValue()); + } + PdfName name = readPdfName(true); + PdfObject obj; + if (PdfName.Contents.equals(name) && searchInV && contentsLevel == currentLevel) { + long startPosition = tokens.getPosition(); + int ch; + int whiteSpacesCount = -1; + do { + ch = tokens.read(); + whiteSpacesCount++; + } while (ch != -1 && PdfTokenizer.isWhitespace(ch)); + tokens.seek(startPosition); + obj = readObject(true, objStm); + long endPosition = tokens.getPosition(); + if (endPosition == contentsEnd && startPosition + whiteSpacesCount == contentsStart) { + rangeIsCorrect = true; + } + } else if (PdfName.V.equals(name) && !searchInV && 1 == currentLevel) { + searchInV = true; + obj = readObject(true, objStm); + searchInV = false; + } else { + obj = readObject(true, objStm); + } + if (obj == null) { + if (tokens.getTokenType() == PdfTokenizer.TokenType.EndDic) + tokens.throwError(PdfException.UnexpectedGtGt); + if (tokens.getTokenType() == PdfTokenizer.TokenType.EndArray) + tokens.throwError(PdfException.UnexpectedCloseBracket); + } + dic.put(name, obj); + } + return dic; + } + + @Override + protected PdfObject readReference(boolean readAsDirect) { + return new PdfNull(); + } + } } diff --git a/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java b/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java index ef5be2248c..6b06fc1f8b 100644 --- a/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java @@ -79,4 +79,93 @@ public void getSignaturesTest02() throws IOException { Assert.assertEquals(0, signatureNames.size()); } + @Test + public void firstBytesNotCoveredTest01() throws IOException { + String inPdf = sourceFolder + "firstBytesNotCoveredTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void lastBytesNotCoveredTest01() throws IOException { + String inPdf = sourceFolder + "lastBytesNotCoveredTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void lastBytesNotCoveredTest02() throws IOException { + String inPdf = sourceFolder + "lastBytesNotCoveredTest02.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void bytesAreNotCoveredTest01() throws IOException { + String inPdf = sourceFolder + "bytesAreNotCoveredTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void bytesAreCoveredTest01() throws IOException { + String inPdf = sourceFolder + "bytesAreCoveredTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void bytesAreCoveredTest02() throws IOException { + String inPdf = sourceFolder + "bytesAreCoveredTest02.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("sig")); + } + + @Test + public void twoContentsTest01() throws IOException { + String inPdf = sourceFolder + "twoContentsTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void spacesBeforeContentsTest01() throws IOException { + String inPdf = sourceFolder + "spacesBeforeContentsTest01.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void spacesBeforeContentsTest02() throws IOException { + String inPdf = sourceFolder + "spacesBeforeContentsTest02.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("Signature1")); + } + + @Test + public void notIndirectSigDictionaryTest() throws IOException { + String inPdf = sourceFolder + "notIndirectSigDictionaryTest.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("Signature1")); + } } diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreCoveredTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreCoveredTest01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3269b79d374dd356f80452c3b8dc48c2773920a0 GIT binary patch literal 18989 zcmeHPTWqCO6&?xT*Z?64qWJQMIMM>sv+oz2G_*5xrVhiDwlKz_A^TbmcFrm1oZ_I- zL^08r_<&IZ2?;zvf~+Z~wi{v=dQyBL6w4*EwmT4v^3d%K-M z>J0i-(Qc-7D8;s$=pH{x@Tau0GJ?&wrdrQri$0}Q|P{#FFSF0!PbpyB9UD%k*H|FjI zR)co8vky=X@4KE6s)(eDa?TmOmhh_yxq75^s2jH%z}5#$_quU8q~36QE*&5Iw9=zw zl`H|@SB_4?4__L0w4$GWkd z+bLGd{dQ+zW&C>(II^*Ax`{#)uAd70tpjQCo-}9&*SfI-CSl3ek#=Xi({Hc;J-h4& z#Q+6NT7TA-+YnqVyK0NQ-DQ}Xwhp#q|7f8NNV0Cd{>GGI@YN~rt15+;YqXdKw{EUz zO;s>!vZ9=|Cg)nS?SP}zK@6DKTa%Skw7lnA6Z?( zd}|IuuK{wT9T(D|H8%{29XD9+B|6f&t)ey4H}+a+xvJB?@!=YAw9I9EEL0=#=ClZ~ zRy_)$;MWWNif;(01+JlW?;y>%&O)l7Hw9ag4Y5$cAh0 z;lwZ^Z6=CX=8O`?sH{mOlxV`-N-tR%WdZ@s3FVYzPA~>@6e)8+eu+V%?w16Q#BVE+ z))Kk4wM4FE{mo=_Wm1vO@D?&Liyw?yS>-IvD5Te`C-JrGy4>Z^8r<5WlBVc95 zNJX4e#(B=8!7A zmU%By42-F4DCJ2;kSe+mEn`Xf6cxNqY0Hd{npsMzhc+_$;F7ekKegbQ30el|5xLXC zgRvlcA|b>iljcr1xHFFwbSBj2EHonqkYwpJ_0||8A|WOb!#VWN2DOx#3Gg4QA!8YFRCSOp_^4WyF*nJ7`p8%M475!;tweT2mlBB2af zY6dJr5|%TgxP< zPz4U+0kg><6fj{ z;b}C(Q)sphgpQh84|i2Yn;>^uS9v23E@%n{tuDv#IhLCa@s42dI=$AV6cJDi~xB zKmfowyp6(Y*nR@RwZoE8J4g&3&I7+g^aoFsCm=rIv_zofRw5DzRU#Dl2ZTPLv3k2q zzWsRtwnFwqR@-_Cu}FR;-*4?fctfV#?&M+#vM$3p0zcrf0*Al{L{ctP^oSC)I4%p( zQ+yBv7sM>;R0O?K9L}-fou+uk|g8c-C&_aT+xX;gfVbYTLEMcF&(8w(iBayR*4LT z%7AR)vN9!05Stl}A_WM&v9iA_7gY_*Y9M zi!)`A3{#<=VnoG-@uj6wn86)O!zfOHS_?DD z^}C(nxzvXg)K*ws&EXpH=+YNMUysH#aN*7rS4v5sM8c-p2%9QCOso|SLAi|zSMKK5 z6yK&&3bR;uqZG;K5Bs}N>H&&P&K#;xr(>-i$y%+4Qeb3d`PHFk6k1_(WXHtL2OoOz zv9~||<`b`d@8sprU9jVGpSa+gTWhJ*ve$|^{0|CqaSnw$*lVe1GSliXl!5raHGg>F zky`OvzdaJpzyCu!F8$-sSGG}qQ}L8_yn*$9!<(AT>ci^q2H4qKmp*dO3sWz>_^0!B zTyo^RliR4XsWi>HI`6{#RI<(bY$`=lS4ml^Me}Y{Tz=`qCEp;I-EjKE;k)=N>>9<#2ch&N1Z++K1@W4|K|6}>8XZ+K*JaXw@ZmiI#{`PA1x_N!lCeBpKfy8GGv-+%OXUwie3qyIkn^oia(ySwp{ z>)+W5)bU=*L!>f88=;}XwQ?@2T&=a?8f;Z}SDp1XTpZofhAXmL+9*evlk(a$7u7Mg zv}q0koi)xdRP$MDvlU&_$Er;-Q3OS;cHp8k%)U0Ee!#t8jiN(mwc+mmS#1P`OwMjY z#Q?o&p%r4+7$dWwtkxPY5+)i&TpZ**gO zaIw`0JX?-C`?%UIQDnj3hHG?+;*P2un{SmuD^+o)nbu6Vi>f*G<81rOsiLUkG_@;6&0e=hU~3p7V2G{#d>-k6Wp-V??az5)%=c1V&?hn z_|yxV2c5<7`ud8Nrh2Y2&2?f9J+H0Qa=)?Ejm4DGYh=Ld{Ny3R}o=bvT;@6##HZyWo-8a2k6LPvcVt69fmFaNJkAkP+FFH=;qleJve!% zVuN_447i*oGH8hmfL3BDm!N9y5V_5jA|T*0?{vz<1WTh01P(Vkh7^;HfRz~|6>&}( z=Q)p#OYV*3#w8OC34%JOjb}Q0;Vn;?Sm}(eG)v)vD!#Ir#L}A*5d#q{5NBDk%zKey zU`%C0DNiyYsGG^ur>F|lVG{v5nXhUo@xVUIBpaR*$^iTcYxY8 zPy=vTylo}Mr<8q6G}G+hBk8=h1ZZiM!7l(3fKZ2h;uc&+3zvaEa7{!|g+J`x<;bW2 z8#=fN>1bF^Jjx(oe9T!RZX5wmoF)<*jv7TG*29jXRMx?)=q-GjqtJ;V^JP#n@MN_v zz9on%nncnnCT^l8L2D5V4U#x6tb!A~2GU6&m?%-o8%M475!;uD`UsCDFrf@tY6dJr z5|%TgxP<*BMx#}Vnyig;iCV#x$%rMcWDe2rz?`=MAz`S@M8d5?AX$>7S`qE7fGJ22 z5136xKmilxv=ccI1*jc!!ul*s3eLe&#)C7`Na^8zWw0RVk|v;l;DSp`89{}l9+^fn zGKFUA5YSOm>yfU?XcMGH27r%sOs?c-h6^l$+XGa}C=j4AQWXr;0}udk zj%=gw8n&Mh;M!rys2yeu9?65e1N$RRl_v;%!YN`Csko$gBdtXI0iky&SFfk!>z@}O z($IRS+S*fyh4>Y{U;6~~hA~CMSD#!E4HyG*X*5(pHSwLRMlBiF_*OWAu)OYAC^o|x z1RNIx^R&c0LWF{d5LSXI4qil<72@F1rUN|2jOTbqqePzTSAmj>Ti5H4xWBm>#Ih!E%CWM^Hi5V2r&B@_XLA*i%KxGIRqgf(as4@JXn%~Ndx0J$&&0O6f|3K99#@<0ws`> zkra}HAZb4>0xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe9 z0xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe90xbe9 z0xbe90_!1wDgvbxL8&!>vIH}o{lnC+9bWR?dhpX>ptr^}bm8U{>uY+!4LiN==AGTj zRfE*OHT5qZuXk*oz8tTy;hi$7C|+Na_A@+rdh)hmns?pBRP7-ZUVf}lBtV%8 zFErC?Z}s1N>XDrjsB4h6&dptYO=p-;N5KtX-$EJ;$Lmtzz=h##H}^J=Z{NOL1HrD; zK$vucG=pCCRcZgNY1j#F35up|xkN(&ht^kiLoar^i>TPpo#+laC%#|n4y0!M$_kXM zv&4<=V4lVV-VFz*U8R}qMmOzOCKKz-wVt^r3|ejADf?KNx73Chm4ay8KdLYR2nW4G z{g4Kyt2$B7^?PAg8diI1)Vrwag>-mW)w2iOVwxOXr$*P=y(m$!y#7qDf1sY6>>WlZ zAQ*_LINMwAaKnD*aJ8pYra)`?zqh_7br**>SIpLBP%*Ef%MPE}?}lkQ!5eA&_Q9~9 z+<~#f4_>xF7RZLlbHD!Jk%#{N!55FbaQ_d_|J6AgcHDE$FN@zt{YF(VO8Ja8zx6Jw zI0nquT~e`fgFXG$Rb`|ihk+HZRE*FF8C^X?=U+UiI78zWE8gapDV8U%KN%f4cZ-+MWK=Nr%b{;s>P`1j{ud+u{r|NLhUd{j=Xg}nsP{}T2y z$moC!is{IE}nMy^>5J(Tn!1^g`JL%!OC8nO@eL6?Vh) zCqO)hGnZ0;HPlMVEr&u_eN;}@94h(RC}vX=sM+QG%7mw=!iW+Y z`fu2OME*;csin&->KC10gT@<6bg(1Ej$0N1X=P;uRG=w}G}u!rCe5E@C|%9eQ*P+? z_ZI7k(C-y#DD{v!X+QS3H1rI`l9tUW+F6w|zRxa6jcSWSSaVIbBsK>A_`{tK~MT5Rv6mbw_RGm3P>&s!bZW z;?y=}4btk=HdLH|-K*MAL19%JIur~~?PnCMSk9`*O&ecl4YAHx z6iiw(R-bJ1uQqn(y@xmQA6ndUm?nvkjGDP^~26t^HE>AX`+MLHPz7QGUjI z;^X#hsuZlr0_8$bA%J;{!Zs15bWl6NFpAgzx9_dXS+HtIY95~b42~5Fe%#bB)RvM( YY-})e{bA!$yyMU1*rrWa?wlF>58C`rCjbBd literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreNotCoveredTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/bytesAreNotCoveredTest01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6b9e2b90f63017e57d6b0fb6b18118bd2afc4aff GIT binary patch literal 18989 zcmeHPTWqCO6&?xT*Z?64qWJQMIMM>sv+oz2G_*5xrVhiDwlKz_A^TbmcFrm1oZ_I- zL^08r_<&IZ2?;zvf~+Z~wi{v=dQyBL6w4*EwmT4v^3d%K-M z>J0i-(Qc-7D8;s$=pH{x@Tau0GJ?&wrdrQri$0}Q|P{#FFSF0!PbpyB9UD%k*H|FjI zR)co8vky=X@4KE6s)(eDa?TmOmhh_yxq75^s2jH%z}5#$_quU8q~36QE*&5Iw9=zw zl`H|@SB_4?4__L0w4$GWkd z+bLGd{dQ+zW&C>(II^*Ax`{#)uAd70tpjQCo-}9&*SfI-CSl3ek#=Xi({Hc;J-h4& z#Q+6NT7TA-+YnqVyK0NQ-DQ}Xwhp#q|7f8NNV0Cd{>GGI@YN~rt15+;YqXdKw{EUz zO;s>!vZ9=|Cg)nS?SP}zK@6DKTa%Skw7lnA6Z?( zd}|IuuK{wT9T(D|H8%{29XD9+B|6f&t)ey4H}+a+xvJB?@!=YAw9I9EEL0=#=ClZ~ zRy_)$;MWWNif;(01+JlW?;y>%&O)l7HS_)NBA$T=ky@yxr%q|S3I=MSMvfKvRyj*E3hDJK%0U;8Q5LIlDWL(}n=rwIL{C7E zTkkRG;UY^V0{RmA!g`-ZpA=ddB~{XbQ>r7gBi3i1E3WyHsOt3WCKwxmAV@NUC2w0gh za6RXgah~(&xa8hgZd@|akRYgY+IXh37vAy&!AfTgrCACWRIwHODVEWch!}`qfjG;O zW!{Sv17j*1N_mnIq>3&?%UDuAMFp=@+A`y#W|mUwp^c0_xFjv?Pc3+6f|db#MDDck zU@XXq`4Cg?#v?voeA|h3(bfDBw0F5y*0*&NQgN2DOx#3Gg4QA!8YFRCSOp_^4WyF*nJ7`p8%M475!;tweT2mlBB2af zY6dJr5|%TgxP< zPz4U+0kg><6fj{ z;b}C(Q)sphgpQh84|i2Yn;>^uS9v23E@%n{tuDv#IhLCa@s42dI=$AV6cJDi~xB zKmfowyp6(Y*nR@RwZoE8J4g&3&I7+g^aoFsCm=rIv_zofRw5DzRU#Dl2ZTPLv3k2q zzWsRtwnFwqR@-_Cu}FR;-*4?fctfV#?&M+#vM$3p0zcrf0*Al{L{ctP^oSC)I4%p( zQ+yBv7sM>;R0O?K9L}-fou+uk|g8c-C&_aT+xX;gfVbYTLEMcF&(8w(iBayR*4LT z%7AR)vN9!05Stl}A_WM&v9iA_7gY_*Y9M zi!)`A3{#<=VnoG-@uj6wn86)O!zfOHS_?DD z^}C(nxzvXg)K*ws&EXpH=+YNMUysH#aN*7rS4v5sM8c-p2%9QCOso|SLAi|zSMKK5 z6yK&&3bR;uqZG;K5Bs}N>H&&P&K#;xr(>-i$y%+4Qeb3d`PHFk6k1_(WXHtL2OoOz zv9~||<`b`d@8sprU9jVGpSa+gTWhJ*ve$|^{0|CqaSnw$*lVe1GSliXl!5raHGg>F zky`OvzdaJpzyCu!F8$-sSGG}qQ}L8_yn*$9!<(AT>ci^q2H4qKmp*dO3sWz>_^0!B zTyo^RliR4XsWi>HI`6{#RI<(bY$`=lS4ml^Me}Y{Tz=`qCEp;I-EjKE;k)=N>>9<#2ch&N1Z++K1@W4|K|6}>8XZ+K*JaXw@ZmiI#{`PA1x_N!lCeBpKfy8GGv-+%OXUwie3qyIkn^oia(ySwp{ z>)+W5)bU=*L!>f88=;}XwQ?@2T&=a?8f;Z}SDp1XTpZofhAXmL+9*evlk(a$7u7Mg zv}q0koi)xdRP$MDvlU&_$Er;-Q3OS;cHp8k%)U0Ee!#t8jiN(mwc+mmS#1P`OwMjY z#Q?o&p%r4+7$dWwtkxPY5+)i&TpZ**gO zaIw`0JX?-C`?%UIQDnj3hHG?+;*P2un{SmuD^+o)nbu6Vi>f*G<81rOsiLUkG_ literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/firstBytesNotCoveredTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/firstBytesNotCoveredTest01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d551f717b831733a7c57a1f8b8d955ee832b5251 GIT binary patch literal 18989 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 literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/lastBytesNotCoveredTest02.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/lastBytesNotCoveredTest02.pdf new file mode 100644 index 0000000000000000000000000000000000000000..353ce79865beff5bb26432ebf1312313e356418a GIT binary patch literal 18989 zcmeHPTWqCO6&?xT*Z?64qWJQMIMM>sv+oz2G_*5xrVhiDwlKz_A^TbmcFrm1oZ_I- zL^08r_<&IZ2?;zvf~+Z~wi{v=brlME-NybN=qj z+G~I7TWjq;?6qrp-{fvOs)u&H{>I6dhh#;nuD@$&&z{y~dvTC@t;t0`(^#{G=jtw1u=-M}XL#I!Dh0hT&vvcYVre?`APrbs`Z9AtO9g(LH{Y;7@5~WdxgVO}ie(RIDB{lltA|UP%4256muKv{I#S46oK) zuYGKbgt>c{62vT|v9Y3DQHf&4DjegX*PZP4j#ai^p^WRVu2xUn>jrMIyRb2rZ_M2b ztOo6FXCI&(-giACR1rxP<(xBmE#X%aa`i~-P&aNjfUOUh?semGNWJ0qTsl7Zd8J3m zDBV4K^Z4}afx~mvPZ%L&cM)FI1FHSK?($M~^KI4b!{hs>Z`yrN>h+<;?IWMBj&)-@ zw^OW^`|Zxc%J}yoaAafKbQ6UpTt5}~TL;qOJ!#Mmu61JvOu~|_Bkj(3r{7-xdv@6m ziUA6kwEnCuw;{M#cGVVpyUQ>&Z5?dK{?S4kkYwF@{f#Nb;Hy(UP*n;q*Jv>fZrxnb znyO&dWJNh^P0qDu+Y7A&t*O?bgBUQewo z_|_bRUIXMvJ1(R_Yi<}4J8rPtOLU}lTSaT8Z|t?ua#g2&V3RwXLeyQ)yduAkqy`0 z!--);+DsI&%o!z&QCX8nDA9zum0q$k$^-(M6Ur&coL~&*C{pHt{1Ssi-7g6qiQiTt zttE18Yl&RT`kTq<%A_Kl;Vooh7C#uZvdUSSQAn>>Q4YFzjIvmbO9>6&-h>GzBzgjR z+=7uNeU`lQgxD5;VboKnpRmFxWu{YhCELu#W1Amb`4rG?gtYNpC+ zXX@c=JuqX7EM8;@5Kdz)m5VG*ur60t#j<`41Z;qT3@RJ^B4U+kD{twjfdxv-$_QQe zoiT!w4=Xm{D`mjt9L%7F833(tDHl@JPmZwqn}QH9nRhy6VuGd71_FZ{9Yc!AM!?F9 zk%~B{jPsmF$0hg1a^sSTh6F*K)5bHMz3`SN2v#~{D9uv1po*>FPqB=K#{DJpoK(v}$?HM5jb4{c=h!6j*7e`>)q6SNG_BXXyO z2V+6@L_&y3Ce592aAzJV=uD{3S!hNKAj#5c>a8(GL_$m=hI8rzyx0l&8pzKro@}s) zhtwDbZu0AM=KKd3aT=wP7z3o{x%1pY}A^AbcCXla!ZUjQTkp$_}RBVrjXu?+D8--!qWUO};Y zmm{MB(a^z6a7V*(;!y?xr#9EDB{o-c!v zfhVhVu`L0sXc9@Qn7E0W1g%9dG)UsOunI=-8b~JrGEt(GH;!8EBepNW`Us09L_!&| z)C^dLBrIn}aS8nkN267Wnyig;iCV#x$>0)KGKXk*V9whBN*F3Lkua+eaF%4LRz!O% zpb8ws17?#!C}6^zb|NRD0JURISf7PS!8vHkcyLAHMVqzNd1Tri0#GpLZ% z!_#Pnr_gL22pu)G9`34)HbH850OGNZ$rV2h4Cal>XU&2KwJp5f1?H2^#_$x2-@=H= z2;&3T5Sc*siZM`x{{&tn&U2s%=z*7T46K$jHsvCPXH(@hOkhE74^SziK!CAyrYlkJHc90l6oCkh~=ntMMPe6RaX^B9|twbacszfO84+wooWA%2K zeEahPY=!KJthV(OVv+nxzTet|@P$aU=j8sYudu zEfhyaXFeN;c&(y9^oayv4PRWRzf4qVo@fvtCV+8BX*qgEB?3t>$d57F z=$wVR$-_-?NbxEMCxfr^pcOcoI4>C_;FRJ8G7vnKQweWE07DW~G9qVD5fNyD#lKoA zS)3_@WS9!=L_xzLKU3xyVi1RO5oFNJ5*Kh1nV}%|g?;3JaBRKS7Rp7)E#6I`FVb#A zcXFNvMEu|Z0^*8C3^UO>T?|cGmefRH1&(n>A!I^4e345R0GU7wtRlQb_An)m0(I>X z@iUV;1j8*9FNp^MOzGr}@PH~9kKk!IbTSEsvJzyXJ|TJ43}`+Y1R4Yy1R4Yy1R4Yy z1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy z1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1R4Yy1U^s%Py;K(>CZ=})b z>4P`52Piqx4Rz^^;r(}_ya$S8oLxWTjPe*ucT6m|7b7Yzj4v&f!VKNsjZ!3EJnZj6sRt-FIdiB&osPA7Bx|)EN`aA;^=J(YzZKmtQ(@$+yU5H=I6k`0oAl z*POWG%9rndhd+MbsVg2|`u&yHUA6q$Ti-ViJn+=R|60E48UOSxk6ik<8>@J5>il1Q z{1-oZ^6P^`{D!yx`n$^?`si~HKl!JLf4+9=Rr}Ighkp7q^S!^{G4;zw|NX?TpSzIU z@}eWLfy z?ryx~`ggVhb-b7I5UI@2Mrf#Tt(?m$S8Hv!23ytLRcE~o7e}|W;fm~*Hp)@vq`WrG zMRklVZJL8XXN@xq)qK|4Y(>}fv1*e{6hTp|9k?hBv#(94A8;>Nqv+6CZMeICRvSSf zle61UF+guxXhj|_+HczUpy%3)saJ|GP3^0W?okofZgG`dI${N`p5mfBF5qTdwGFt@ z8{OC*Tx>N0&z9rPKCX646j?C1;ToNyxT7k^=3AxEN>$uxrZv;;qH0e4INSbeswnC> h4ehFH1?@hwme5dt;Ch4Fn&ql58QQh$#>10C{{xmr#eDz( literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/notIndirectSigDictionaryTest.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/notIndirectSigDictionaryTest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4fce05752b4b4df21a32c538e915f9e708365fa5 GIT binary patch literal 18954 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 Vf$I(Gh@lY#;X^xj?!9?x=wGHz$v^-A literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/spacesBeforeContentsTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/spacesBeforeContentsTest01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..237565607da236f603a53facf45a3b4b31777b72 GIT binary patch literal 18989 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 literal 0 HcmV?d00001 diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/twoContentsTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/twoContentsTest01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..802465bad39e585b248cf2ec0a311148ef1da745 GIT binary patch literal 18989 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 et`)TN%vwUN!O-=GwKdCCU((vK