Skip to content

Commit

Permalink
Merge branch 'develop' into devsecops
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-ivanov committed Jan 26, 2024
2 parents 9559800 + 116ce7f commit d75a0e6
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 15 deletions.
15 changes: 3 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,11 @@ Please read our [Contribution Guidelines][contributing] for details on code subm

**iText** is dual licensed as [AGPL][agpl]/[Commercial software][sales].

AGPL is a free / open source software license.
AGPL is a free/open-source software license, however, this doesn't mean the software is [gratis][gratis]!

This doesn't mean the software is [gratis][gratis]!
The AGPL is a copyleft license, which means that any derivative work must also be licensed under the same terms. If you’re using iText in software or a service which cannot comply with the AGPL terms, we have a commercial license available that exempts you from such obligations.

Buying a license is mandatory as soon as you develop commercial activities
distributing the iText software inside your product or deploying it on a network
without disclosing the source code of your own applications under the AGPL license.
These activities include:

- offering paid services to customers as an ASP
- serving PDFs on the fly in the cloud or in a web application
- shipping iText with a closed source product

Contact [sales] for more info.
Contact [Sales] for more info.

[agpl]: LICENSE.md

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using iText.IO.Source;
using iText.Kernel.Exceptions;
using iText.Test;

Expand Down Expand Up @@ -108,5 +109,71 @@ public virtual void ZeroCapacityInConstructorWithHandlerTest() {
PdfXrefTable xrefTable = new PdfXrefTable(0, memoryLimitsAwareHandler);
NUnit.Framework.Assert.AreEqual(20, xrefTable.GetCapacity());
}

[NUnit.Framework.Test]
public virtual void XRefMaxValueLong() {
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
document.xref.Add(new PdfIndirectReferenceProxy(document, 11, long.MaxValue));
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => {
document.Close();
}
);
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.XREF_HAS_AN_ENTRY_WITH_TOO_BIG_OFFSET, e.Message
);
}

[NUnit.Framework.Test]
public virtual void MaxCrossReferenceOffSetReached() {
long justOver10gbLogical = 10_000_000_001L;
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
document.xref.Add(new PdfIndirectReferenceProxy(document, 11, justOver10gbLogical));
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => {
document.Close();
}
);
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.XREF_HAS_AN_ENTRY_WITH_TOO_BIG_OFFSET, e.Message
);
}

[NUnit.Framework.Test]
public virtual void MaxCrossReference() {
long justOver10gbLogical = 10_000_000_000L;
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
document.xref.Add(new PdfIndirectReferenceProxy(document, 11, justOver10gbLogical));
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => {
document.Close();
}
);
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.XREF_HAS_AN_ENTRY_WITH_TOO_BIG_OFFSET, e.Message
);
}

[NUnit.Framework.Test]
public virtual void JustBelowXrefThreshold() {
long maxAllowedOffset = 10_000_000_000L - 1L;
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
document.xref.Add(new PdfIndirectReferenceProxy(document, 11, maxAllowedOffset));
NUnit.Framework.Assert.DoesNotThrow(() => document.Close());
}

[NUnit.Framework.Test]
public virtual void XRefIntMax() {
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
document.xref.Add(new PdfIndirectReferenceProxy(document, 11, int.MaxValue));
NUnit.Framework.Assert.DoesNotThrow(() => document.Close());
}
}

internal class PdfIndirectReferenceProxy : PdfIndirectReference {
private readonly long offset;

public PdfIndirectReferenceProxy(PdfDocument document, int objNumber, long offset)
: base(document, objNumber) {
this.offset = offset;
}

public override long GetOffset() {
return offset;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ public const String WHEN_ADDING_OBJECT_REFERENCE_TO_THE_TAG_TREE_IT_MUST_BE_CONN

public const String ARG_SHOULD_NOT_BE_NULL = "{0} should not be null.";

public const String XREF_HAS_AN_ENTRY_WITH_TOO_BIG_OFFSET = "Pdf document is to large to " + "use normal cross reference table. Use cross reference streams instead. To enable feature use com.itextpdf"
+ ".kernel.pdf.WriterProperties#setFullCompressionMode(true). ";

private KernelExceptionMessageConstant() {
}
}
Expand Down
14 changes: 14 additions & 0 deletions itext/itext.kernel/itext/kernel/pdf/PdfXrefTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Utils;
using iText.IO.Source;
using iText.Kernel.Actions.Data;
using iText.Kernel.Exceptions;

namespace iText.Kernel.Pdf {
/// <summary>A representation of a cross-referenced table of a PDF document.</summary>
Expand All @@ -37,6 +38,16 @@ public class PdfXrefTable {

private const int MAX_GENERATION = 65535;

/// <summary>The maximum offset in a cross-reference stream.</summary>
/// <remarks>
/// The maximum offset in a cross-reference stream. This is a limitation of the PDF specification.
/// SPEC1.7: 7.5.4 Cross reference trailer
/// <para />
/// It states that the offset should be a 10-digit byte, so the maximum value is 9999999999.
/// This is the max value that can be represented in 10 bytes.
/// </remarks>
private const long MAX_OFFSET_IN_CROSS_REFERENCE_STREAM = 9_999_999_999L;

private static readonly byte[] freeXRefEntry = ByteUtils.GetIsoBytes("f \n");

private static readonly byte[] inUseXRefEntry = ByteUtils.GetIsoBytes("n \n");
Expand Down Expand Up @@ -352,6 +363,9 @@ protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, P
writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n');
for (int i = first; i < first + len; i++) {
PdfIndirectReference reference = xrefTable.Get(i);
if (reference.GetOffset() > MAX_OFFSET_IN_CROSS_REFERENCE_STREAM) {
throw new PdfException(KernelExceptionMessageConstant.XREF_HAS_AN_ENTRY_WITH_TOO_BIG_OFFSET);
}
StringBuilder off = new StringBuilder("0000000000").Append(reference.GetOffset());
StringBuilder gen = new StringBuilder("00000").Append(reference.GetGenNumber());
writer.WriteString(off.JSubstring(off.Length - 10, off.Length)).WriteSpace().WriteString(gen.JSubstring(gen
Expand Down
59 changes: 59 additions & 0 deletions itext/itext.sign/itext/signatures/PadesTwoPhaseSigningHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,25 @@ public virtual iText.Signatures.PadesTwoPhaseSigningHelper SetStampingProperties
return this;
}

/// <summary>Creates CMS container compliant with PAdES level.</summary>
/// <remarks>
/// Creates CMS container compliant with PAdES level. Prepares document and placeholder for the future signature
/// without actual signing process.
/// </remarks>
/// <param name="certificates">certificates to be added to the CMS container</param>
/// <param name="digestAlgorithm">the algorithm to generate the digest with</param>
/// <param name="inputDocument">
/// reader
/// <see cref="iText.Kernel.Pdf.PdfReader"/>
/// instance to read original PDF file
/// </param>
/// <param name="outputStream">
///
/// <see cref="System.IO.Stream"/>
/// output stream to write the resulting PDF file into
/// </param>
/// <param name="signerProperties">properties to be used in the signing operations</param>
/// <returns>prepared CMS container without signature.</returns>
public virtual CMSContainer CreateCMSContainerWithoutSignature(IX509Certificate[] certificates, String digestAlgorithm
, PdfReader inputDocument, Stream outputStream, SignerProperties signerProperties) {
IX509Certificate[] fullChain = issuingCertificateRetriever.RetrieveMissingCertificates(certificates);
Expand All @@ -328,6 +347,16 @@ public virtual CMSContainer CreateCMSContainerWithoutSignature(IX509Certificate[
return cms;
}

/// <summary>Follow-up step that signs prepared document with PAdES Baseline-B profile.</summary>
/// <param name="externalSignature">external signature to do the actual signing</param>
/// <param name="inputDocument">
/// reader
/// <see cref="iText.Kernel.Pdf.PdfReader"/>
/// instance to read prepared document
/// </param>
/// <param name="outputStream">the output PDF</param>
/// <param name="signatureFieldName">the field to sign</param>
/// <param name="cmsContainer">the finalized CMS container (e.g. created in the first step)</param>
public virtual void SignCMSContainerWithBaselineBProfile(IExternalSignature externalSignature, PdfReader inputDocument
, Stream outputStream, String signatureFieldName, CMSContainer cmsContainer) {
SetSignatureAlgorithmAndSignature(externalSignature, cmsContainer);
Expand All @@ -341,6 +370,16 @@ public virtual void SignCMSContainerWithBaselineBProfile(IExternalSignature exte
}
}

/// <summary>Follow-up step that signs prepared document with PAdES Baseline-T profile.</summary>
/// <param name="externalSignature">external signature to do the actual signing</param>
/// <param name="inputDocument">
/// reader
/// <see cref="iText.Kernel.Pdf.PdfReader"/>
/// instance to read prepared document
/// </param>
/// <param name="outputStream">the output PDF</param>
/// <param name="signatureFieldName">the field to sign</param>
/// <param name="cmsContainer">the finalized CMS container (e.g. created in the first step)</param>
public virtual void SignCMSContainerWithBaselineTProfile(IExternalSignature externalSignature, PdfReader inputDocument
, Stream outputStream, String signatureFieldName, CMSContainer cmsContainer) {
byte[] signature = SetSignatureAlgorithmAndSignature(externalSignature, cmsContainer);
Expand All @@ -365,6 +404,16 @@ public virtual void SignCMSContainerWithBaselineTProfile(IExternalSignature exte
}
}

/// <summary>Follow-up step that signs prepared document with PAdES Baseline-LT profile.</summary>
/// <param name="externalSignature">external signature to do the actual signing</param>
/// <param name="inputDocument">
/// reader
/// <see cref="iText.Kernel.Pdf.PdfReader"/>
/// instance to read prepared document
/// </param>
/// <param name="outputStream">the output PDF</param>
/// <param name="signatureFieldName">the field to sign</param>
/// <param name="cmsContainer">the finalized CMS container (e.g. created in the first step)</param>
public virtual void SignCMSContainerWithBaselineLTProfile(IExternalSignature externalSignature, PdfReader
inputDocument, Stream outputStream, String signatureFieldName, CMSContainer cmsContainer) {
PdfPadesSigner padesSigner = CreatePadesSigner(inputDocument, outputStream);
Expand All @@ -387,6 +436,16 @@ public virtual void SignCMSContainerWithBaselineLTProfile(IExternalSignature ext
}
}

/// <summary>Follow-up step that signs prepared document with PAdES Baseline-LTA profile.</summary>
/// <param name="externalSignature">external signature to do the actual signing</param>
/// <param name="inputDocument">
/// reader
/// <see cref="iText.Kernel.Pdf.PdfReader"/>
/// instance to read prepared document
/// </param>
/// <param name="outputStream">the output PDF</param>
/// <param name="signatureFieldName">the field to sign</param>
/// <param name="cmsContainer">the finalized CMS container (e.g. created in the first step)</param>
public virtual void SignCMSContainerWithBaselineLTAProfile(IExternalSignature externalSignature, PdfReader
inputDocument, Stream outputStream, String signatureFieldName, CMSContainer cmsContainer) {
PdfPadesSigner padesSigner = CreatePadesSigner(inputDocument, outputStream);
Expand Down
2 changes: 1 addition & 1 deletion itext/itext.sign/itext/signatures/cms/CMSContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public virtual void AddCertificates(IX509Certificate[] certs) {
}

/// <summary>Retrieves a copy of the list of certificates.</summary>
/// <returns>the list of certificates to be used for signing and certificate validation</returns>
/// <returns>the list of certificates to be used for signing and certificate validation</returns>
public virtual ICollection<IX509Certificate> GetCertificates() {
return JavaCollectionsUtil.UnmodifiableCollection(certificates);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public sealed class SignExceptionMessageConstant {

public const String TOO_BIG_KEY = "The key is too big.";

public const String TSA_CLIENT_IS_MISSING = "ITSAClient must be present to rich this PAdES level. " + "Please use setTSAClient method to provide it.";
public const String TSA_CLIENT_IS_MISSING = "ITSAClient must be present to reach this PAdES level. " + "Please use setTSAClient method to provide it.";

public const String UNEXPECTED_CLOSE_BRACKET = "Unexpected close bracket.";

Expand Down
2 changes: 1 addition & 1 deletion port-hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
244cfd2ca06225d2c71eca0466283f88c78e3ae0
72fcf3610d2927697378f097c5fe87f445d0578d

0 comments on commit d75a0e6

Please sign in to comment.