Skip to content

Commit c810622

Browse files
author
Alexander Kozlov
committed
Fix for consiquent signatures verification by preventing copying of existing RandomAccessSource
DEVSIX-6181
1 parent 0527a1e commit c810622

File tree

10 files changed

+254
-59
lines changed

10 files changed

+254
-59
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2022 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
using System;
44+
using System.IO;
45+
using iText.IO.Exceptions;
46+
using iText.Test;
47+
48+
namespace iText.IO.Source {
49+
public class RandomAccessSourceFactoryTest : ExtendedITextTest {
50+
private static readonly String SOURCE_FILE = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
51+
.CurrentContext.TestDirectory) + "/resources/itext/io/source/RAF.txt";
52+
53+
[NUnit.Framework.Test]
54+
public virtual void ReadRASInputStreamClosedTest() {
55+
String fileName = SOURCE_FILE;
56+
using (Stream pdfStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
57+
IRandomAccessSource randomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(pdfStream);
58+
RASInputStream rasInputStream = new RASInputStream(randomAccessSource);
59+
IRandomAccessSource extractedRandomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(rasInputStream
60+
);
61+
extractedRandomAccessSource.Close();
62+
Exception e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => rasInputStream.Read());
63+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
64+
e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => randomAccessSource.Get(0));
65+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
66+
e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => randomAccessSource.Get(0, new byte
67+
[10], 0, 10));
68+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
69+
e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => randomAccessSource.Length());
70+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
71+
}
72+
}
73+
74+
[NUnit.Framework.Test]
75+
public virtual void ReadRASInputStreamTest() {
76+
String fileName = SOURCE_FILE;
77+
using (Stream pdfStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
78+
IRandomAccessSource randomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(pdfStream);
79+
RASInputStream rasInputStream = new RASInputStream(randomAccessSource);
80+
IRandomAccessSource extractedRandomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(rasInputStream
81+
);
82+
NUnit.Framework.Assert.AreEqual(72, rasInputStream.Read());
83+
NUnit.Framework.Assert.AreEqual(72, extractedRandomAccessSource.Get(0));
84+
NUnit.Framework.Assert.AreEqual(extractedRandomAccessSource, rasInputStream.GetSource());
85+
}
86+
}
87+
}
88+
}

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfReaderTest.cs

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ source product.
4444
using System.Collections.Generic;
4545
using System.IO;
4646
using iText.Commons.Utils;
47+
using iText.IO.Exceptions;
4748
using iText.IO.Font;
4849
using iText.IO.Source;
4950
using iText.Kernel.Exceptions;
@@ -1512,12 +1513,12 @@ public virtual void HasRebuiltXrefPdfDocumentNotReadTest() {
15121513
[NUnit.Framework.Test]
15131514
public virtual void HasRebuiltXrefReadingNotCompletedTest() {
15141515
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1515-
PdfReader hasRebuiltXrefReader = new _PdfReader_1756(filename);
1516+
PdfReader hasRebuiltXrefReader = new _PdfReader_1758(filename);
15161517
ReadingNotCompletedTest(hasRebuiltXrefReader);
15171518
}
15181519

1519-
private sealed class _PdfReader_1756 : PdfReader {
1520-
public _PdfReader_1756(String baseArg1)
1520+
private sealed class _PdfReader_1758 : PdfReader {
1521+
public _PdfReader_1758(String baseArg1)
15211522
: base(baseArg1) {
15221523
}
15231524

@@ -1538,12 +1539,12 @@ public virtual void HasHybridXrefPdfDocumentNotReadTest() {
15381539
[NUnit.Framework.Test]
15391540
public virtual void HasHybridXrefReadingNotCompletedTest() {
15401541
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1541-
PdfReader hasHybridXrefPdfReader = new _PdfReader_1779(filename);
1542+
PdfReader hasHybridXrefPdfReader = new _PdfReader_1781(filename);
15421543
ReadingNotCompletedTest(hasHybridXrefPdfReader);
15431544
}
15441545

1545-
private sealed class _PdfReader_1779 : PdfReader {
1546-
public _PdfReader_1779(String baseArg1)
1546+
private sealed class _PdfReader_1781 : PdfReader {
1547+
public _PdfReader_1781(String baseArg1)
15471548
: base(baseArg1) {
15481549
}
15491550

@@ -1563,12 +1564,12 @@ public virtual void HasXrefStmPdfDocumentNotReadTest() {
15631564
[NUnit.Framework.Test]
15641565
public virtual void HasXrefStmReadingNotCompletedTest() {
15651566
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1566-
PdfReader hasXrefStmReader = new _PdfReader_1802(filename);
1567+
PdfReader hasXrefStmReader = new _PdfReader_1804(filename);
15671568
ReadingNotCompletedTest(hasXrefStmReader);
15681569
}
15691570

1570-
private sealed class _PdfReader_1802 : PdfReader {
1571-
public _PdfReader_1802(String baseArg1)
1571+
private sealed class _PdfReader_1804 : PdfReader {
1572+
public _PdfReader_1804(String baseArg1)
15721573
: base(baseArg1) {
15731574
}
15741575

@@ -1588,12 +1589,12 @@ public virtual void HasFixedXrefPdfDocumentNotReadTest() {
15881589
[NUnit.Framework.Test]
15891590
public virtual void HasFixedXrefReadingNotCompletedTest() {
15901591
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1591-
PdfReader hasFixedXrefReader = new _PdfReader_1825(filename);
1592+
PdfReader hasFixedXrefReader = new _PdfReader_1827(filename);
15921593
ReadingNotCompletedTest(hasFixedXrefReader);
15931594
}
15941595

1595-
private sealed class _PdfReader_1825 : PdfReader {
1596-
public _PdfReader_1825(String baseArg1)
1596+
private sealed class _PdfReader_1827 : PdfReader {
1597+
public _PdfReader_1827(String baseArg1)
15971598
: base(baseArg1) {
15981599
}
15991600

@@ -1613,12 +1614,12 @@ public virtual void GetLastXrefPdfDocumentNotReadTest() {
16131614
[NUnit.Framework.Test]
16141615
public virtual void GetLastXrefReadingNotCompletedTest() {
16151616
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1616-
PdfReader getLastXrefReader = new _PdfReader_1848(filename);
1617+
PdfReader getLastXrefReader = new _PdfReader_1850(filename);
16171618
ReadingNotCompletedTest(getLastXrefReader);
16181619
}
16191620

1620-
private sealed class _PdfReader_1848 : PdfReader {
1621-
public _PdfReader_1848(String baseArg1)
1621+
private sealed class _PdfReader_1850 : PdfReader {
1622+
public _PdfReader_1850(String baseArg1)
16221623
: base(baseArg1) {
16231624
}
16241625

@@ -1639,12 +1640,12 @@ public virtual void GetPermissionsPdfDocumentNotReadTest() {
16391640
[NUnit.Framework.Test]
16401641
public virtual void GetPermissionsReadingNotCompletedTest() {
16411642
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1642-
PdfReader getPermissionsReader = new _PdfReader_1871(filename);
1643+
PdfReader getPermissionsReader = new _PdfReader_1873(filename);
16431644
ReadingNotCompletedTest(getPermissionsReader);
16441645
}
16451646

1646-
private sealed class _PdfReader_1871 : PdfReader {
1647-
public _PdfReader_1871(String baseArg1)
1647+
private sealed class _PdfReader_1873 : PdfReader {
1648+
public _PdfReader_1873(String baseArg1)
16481649
: base(baseArg1) {
16491650
}
16501651

@@ -1665,12 +1666,12 @@ public virtual void IsOpenedWithFullPPdfDocumentNotReadTest() {
16651666
[NUnit.Framework.Test]
16661667
public virtual void IsOpenedWithFullPReadingNotCompletedTest() {
16671668
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1668-
PdfReader isOpenedWithFullPReader = new _PdfReader_1896(filename);
1669+
PdfReader isOpenedWithFullPReader = new _PdfReader_1898(filename);
16691670
ReadingNotCompletedTest(isOpenedWithFullPReader);
16701671
}
16711672

1672-
private sealed class _PdfReader_1896 : PdfReader {
1673-
public _PdfReader_1896(String baseArg1)
1673+
private sealed class _PdfReader_1898 : PdfReader {
1674+
public _PdfReader_1898(String baseArg1)
16741675
: base(baseArg1) {
16751676
}
16761677

@@ -1691,12 +1692,12 @@ public virtual void GetCryptoModePdfDocumentNotReadTest() {
16911692
[NUnit.Framework.Test]
16921693
public virtual void GetCryptoModeReadingNotCompletedTest() {
16931694
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1694-
PdfReader getCryptoModeReader = new _PdfReader_1919(filename);
1695+
PdfReader getCryptoModeReader = new _PdfReader_1921(filename);
16951696
ReadingNotCompletedTest(getCryptoModeReader);
16961697
}
16971698

1698-
private sealed class _PdfReader_1919 : PdfReader {
1699-
public _PdfReader_1919(String baseArg1)
1699+
private sealed class _PdfReader_1921 : PdfReader {
1700+
public _PdfReader_1921(String baseArg1)
17001701
: base(baseArg1) {
17011702
}
17021703

@@ -1717,12 +1718,12 @@ public virtual void ComputeUserPasswordPdfDocumentNotReadTest() {
17171718
[NUnit.Framework.Test]
17181719
public virtual void ComputeUserPasswordReadingNotCompletedTest() {
17191720
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1720-
PdfReader computeUserPasswordReader = new _PdfReader_1944(filename);
1721+
PdfReader computeUserPasswordReader = new _PdfReader_1946(filename);
17211722
ReadingNotCompletedTest(computeUserPasswordReader);
17221723
}
17231724

1724-
private sealed class _PdfReader_1944 : PdfReader {
1725-
public _PdfReader_1944(String baseArg1)
1725+
private sealed class _PdfReader_1946 : PdfReader {
1726+
public _PdfReader_1946(String baseArg1)
17261727
: base(baseArg1) {
17271728
}
17281729

@@ -1743,12 +1744,12 @@ public virtual void GetOriginalFileIdPdfDocumentNotReadTest() {
17431744
[NUnit.Framework.Test]
17441745
public virtual void GetOriginalFileIdReadingNotCompletedTest() {
17451746
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1746-
PdfReader getOriginalFileIdReader = new _PdfReader_1967(filename);
1747+
PdfReader getOriginalFileIdReader = new _PdfReader_1969(filename);
17471748
ReadingNotCompletedTest(getOriginalFileIdReader);
17481749
}
17491750

1750-
private sealed class _PdfReader_1967 : PdfReader {
1751-
public _PdfReader_1967(String baseArg1)
1751+
private sealed class _PdfReader_1969 : PdfReader {
1752+
public _PdfReader_1969(String baseArg1)
17521753
: base(baseArg1) {
17531754
}
17541755

@@ -1769,12 +1770,12 @@ public virtual void GetModifiedFileIdPdfDocumentNotReadTest() {
17691770
[NUnit.Framework.Test]
17701771
public virtual void GetModifiedFileIdReadingNotCompletedTest() {
17711772
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1772-
PdfReader getModifiedFileIdReader = new _PdfReader_1990(filename);
1773+
PdfReader getModifiedFileIdReader = new _PdfReader_1992(filename);
17731774
ReadingNotCompletedTest(getModifiedFileIdReader);
17741775
}
17751776

1776-
private sealed class _PdfReader_1990 : PdfReader {
1777-
public _PdfReader_1990(String baseArg1)
1777+
private sealed class _PdfReader_1992 : PdfReader {
1778+
public _PdfReader_1992(String baseArg1)
17781779
: base(baseArg1) {
17791780
}
17801781

@@ -1794,12 +1795,12 @@ public virtual void IsEncryptedPdfDocumentNotReadTest() {
17941795
[NUnit.Framework.Test]
17951796
public virtual void IsEncryptedReadingNotCompletedTest() {
17961797
String filename = SOURCE_FOLDER + "XrefWithNullOffsets.pdf";
1797-
PdfReader isEncryptedReader = new _PdfReader_2013(filename);
1798+
PdfReader isEncryptedReader = new _PdfReader_2015(filename);
17981799
ReadingNotCompletedTest(isEncryptedReader);
17991800
}
18001801

1801-
private sealed class _PdfReader_2013 : PdfReader {
1802-
public _PdfReader_2013(String baseArg1)
1802+
private sealed class _PdfReader_2015 : PdfReader {
1803+
public _PdfReader_2015(String baseArg1)
18031804
: base(baseArg1) {
18041805
}
18051806

@@ -1994,6 +1995,46 @@ public virtual void ClosingArrayBracketMissingConservativeTest() {
19941995
"obj"), exception.InnerException.Message);
19951996
}
19961997

1998+
[NUnit.Framework.Test]
1999+
public virtual void ReadRASInputStreamClosedTest() {
2000+
String fileName = SOURCE_FOLDER + "hello.pdf";
2001+
using (Stream pdfStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
2002+
IRandomAccessSource randomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(pdfStream);
2003+
RASInputStream rasInputStream = new RASInputStream(randomAccessSource);
2004+
randomAccessSource.Close();
2005+
Exception e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => new PdfReader(rasInputStream
2006+
));
2007+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
2008+
}
2009+
}
2010+
2011+
[NUnit.Framework.Test]
2012+
public virtual void ReadRASInputStreamTest() {
2013+
String fileName = SOURCE_FOLDER + "hello.pdf";
2014+
using (Stream pdfStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
2015+
IRandomAccessSource randomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(pdfStream);
2016+
RASInputStream rasInputStream = new RASInputStream(randomAccessSource);
2017+
using (PdfReader reader = new PdfReader(rasInputStream)) {
2018+
randomAccessSource.Close();
2019+
Exception e = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => new PdfDocument(reader
2020+
));
2021+
NUnit.Framework.Assert.AreEqual(IoExceptionMessage.ALREADY_CLOSED, e.Message);
2022+
}
2023+
}
2024+
}
2025+
2026+
[NUnit.Framework.Test]
2027+
public virtual void ReadRASInputStreamValidTest() {
2028+
String fileName = SOURCE_FOLDER + "hello.pdf";
2029+
using (Stream pdfStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
2030+
IRandomAccessSource randomAccessSource = new RandomAccessSourceFactory().ExtractOrCreateSource(pdfStream);
2031+
RASInputStream rasInputStream = new RASInputStream(randomAccessSource);
2032+
using (PdfReader reader = new PdfReader(rasInputStream)) {
2033+
NUnit.Framework.Assert.DoesNotThrow(() => new PdfDocument(reader));
2034+
}
2035+
}
2036+
}
2037+
19972038
private static FileInfo CopyFileForTest(String fileName, String copiedFileName) {
19982039
FileInfo copiedFile = new FileInfo(copiedFileName);
19992040
File.Copy(System.IO.Path.Combine(fileName), System.IO.Path.Combine(copiedFileName));

itext.tests/itext.sign.tests/itext/signatures/LtvVerifierIntegrationTest.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,23 @@ public virtual void NotTrustedRootCertificateInLatestRevisionTest() {
227227
NUnit.Framework.Assert.AreEqual("Root certificate passed without checking", verificationOK.message);
228228
}
229229
}
230+
231+
[NUnit.Framework.Test]
232+
public virtual void SwitchBetweenSeveralRevisionsTest() {
233+
String testInput = SOURCE_FOLDER + "severalConsequentSignatures.pdf";
234+
using (PdfReader pdfReader = new PdfReader(testInput)) {
235+
using (PdfDocument pdfDoc = new PdfDocument(pdfReader)) {
236+
LtvVerifier ltvVerifier = new LtvVerifier(pdfDoc);
237+
NUnit.Framework.Assert.AreEqual("timestampSig2", ltvVerifier.signatureName);
238+
ltvVerifier.SwitchToPreviousRevision();
239+
NUnit.Framework.Assert.AreEqual("Signature2", ltvVerifier.signatureName);
240+
ltvVerifier.SwitchToPreviousRevision();
241+
NUnit.Framework.Assert.AreEqual("timestampSig1", ltvVerifier.signatureName);
242+
ltvVerifier.SwitchToPreviousRevision();
243+
NUnit.Framework.Assert.AreEqual("Signature1", ltvVerifier.signatureName);
244+
ltvVerifier.SwitchToPreviousRevision();
245+
}
246+
}
247+
}
230248
}
231249
}

itext/itext.io/itext/io/exceptions/IoExceptionMessage.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,7 @@ public sealed class IoExceptionMessage {
6363
public const String IMAGE_MAGICK_OUTPUT_IS_NULL = "ImageMagick process output is null.";
6464

6565
public const String IMAGE_MAGICK_PROCESS_EXECUTION_FAILED = "ImageMagick process execution finished with errors: ";
66+
67+
public const String ALREADY_CLOSED = "Already closed";
6668
}
6769
}

0 commit comments

Comments
 (0)