Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing wiki examples #1139

Merged
merged 2 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pdf-toolbox/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
<groupId>org.jfree</groupId>
<artifactId>jcommon</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<optional>true</optional>
</dependency>

<!-- Test Dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public static void main(String[] args) {
String[][] names = bf.getFullFontName();
out.write("\n\nListing the full font name:\n\n");
for (String[] name : names) {
if (name[0].equals("3") && name[1].equals("1")) // Microsoft encoding
{
// Microsoft encoding
if (name[0].equals("3") && name[1].equals("1")) {
out.write(name[3] + "\r\n");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.lowagie.examples.objects;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfPageEventHelper;
import com.lowagie.text.pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class HeaderAndFooter extends PdfPageEventHelper {

public static void main(String[] args) throws DocumentException, FileNotFoundException {

System.out.println("Header and footer");

// step 1: create a document object with margin size based on the header and footer content
Document document = new Document(PageSize.A4, 36, 36, 65, 36);

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("HeaderAndFooter.pdf"));
writer.setPageEvent(new HeaderAndFooter());
document.open();

Paragraph page1Body = new Paragraph("Page one content.");
page1Body.setAlignment(Element.ALIGN_CENTER);
document.add(page1Body);

document.close();
writer.close();
}

@Override
public void onStartPage(PdfWriter writer, Document document) {

// step 2: create a header
PdfPTable table = new PdfPTable(3);
table.setTotalWidth(510);
table.setWidths(new int[]{38, 36, 36});
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setPaddingBottom(5);
table.getDefaultCell().setBorder(Rectangle.BOTTOM);

PdfPCell emptyCell = new PdfPCell(new Paragraph(""));
emptyCell.setBorder(Rectangle.NO_BORDER);

table.addCell(emptyCell);
Paragraph title = new Paragraph("Header", new Font(Font.COURIER, 20, Font.BOLD));
PdfPCell titleCell = new PdfPCell(title);
titleCell.setPaddingBottom(10);
titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
titleCell.setBorder(Rectangle.NO_BORDER);
table.addCell(titleCell);
table.addCell(emptyCell);

Font cellFont = new Font(Font.HELVETICA, 8);
table.addCell(new Paragraph("Phone Number: 888-999-0000", cellFont));
table.addCell(new Paragraph("Address : 333, Manhattan, New York", cellFont));
table.addCell(new Paragraph("Website : http://grogu-yoda.com", cellFont));

table.writeSelectedRows(0, -1, 34, 828, writer.getDirectContent());
}

@Override
public void onEndPage(PdfWriter writer, Document document) {

// step 3: create a footer
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(510);
table.setWidths(new int[]{50, 50});
table.getDefaultCell().setPaddingBottom(5);
table.getDefaultCell().setBorder(Rectangle.TOP);

Paragraph title = new Paragraph("Footer", new Font(Font.HELVETICA, 10));
PdfPCell titleCell = new PdfPCell(title);
titleCell.setPaddingTop(4);
titleCell.setHorizontalAlignment(Element.ALIGN_LEFT);
titleCell.setBorder(Rectangle.TOP);
table.addCell(titleCell);

Paragraph pageNumberText = new Paragraph("Page " + document.getPageNumber(), new Font(Font.HELVETICA, 10));
PdfPCell pageNumberCell = new PdfPCell(pageNumberText);
pageNumberCell.setPaddingTop(4);
pageNumberCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
pageNumberCell.setBorder(Rectangle.TOP);
table.addCell(pageNumberCell);

table.writeSelectedRows(0, -1, 34, 36, writer.getDirectContent());
}
}
144 changes: 144 additions & 0 deletions pdf-toolbox/src/test/java/com/lowagie/examples/objects/Signing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.lowagie.examples.objects;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfDate;
import com.lowagie.text.pdf.PdfDictionary;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfPKCS7;
import com.lowagie.text.pdf.PdfPKCS7.X509Name;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfString;
import com.lowagie.text.pdf.PdfWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Signing {

public static void main(String[] args) {
try {
addUnverifiedSignature(true);
addUnverifiedSignature(false);
extractVerifiedCryptoSignature();

} catch (DocumentException e) {
System.err.println(e.getMessage());
}
}

private static void addUnverifiedSignature(boolean visible) {
try {
String visibility = visible ? "visible" : "invisible";
String description = "Document with " + visibility + " signature";
System.out.println(description);

Document document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
writer.getInfo().put(PdfName.CREATOR, new PdfString(Document.getVersion()));

document.add(new Paragraph(description));
document.close();

PdfReader reader = new PdfReader(baos.toByteArray());
// A verified signature would require a private key plus a valid certificate. see the JavaDoc of this
// method for details
PdfStamper stp = PdfStamper.createSignature(reader, baos, '\0', null, true);

Calendar signDate = Calendar.getInstance();
stp.setEnforcedModificationDate(signDate);

PdfSignatureAppearance sap = stp.getSignatureAppearance();
PdfDictionary dic = new PdfDictionary();
// self signed
dic.put(PdfName.FILTER, PdfName.ADOBE_PPKLITE);
dic.put(PdfName.M, new PdfDate(signDate));
sap.setCryptoDictionary(dic);
sap.setSignDate(signDate);

if (visible) {
sap.setVisibleSignature(new Rectangle(100, 100), 1);
sap.setLayer2Text("Test signer");
}

// exclude the signature from the hash of the PDF and fill the resulting gap
Map<PdfName, Integer> exc = new HashMap<>();
exc.put(PdfName.CONTENTS, 10);
sap.preClose(exc);
PdfDictionary update = new PdfDictionary();
update.put(PdfName.CONTENTS, new PdfString("aaaa").setHexWriting(true));
sap.close(update);

String fileNamePrefix = visibility.substring(0, 1).toUpperCase() + visibility.substring(1);
FileOutputStream fos = new FileOutputStream(fileNamePrefix + "Signature.pdf");
fos.write(baos.toByteArray());
fos.close();

InputStream resultIS = new ByteArrayInputStream(baos.toByteArray());
PdfReader resultReader = new PdfReader(resultIS);

AcroFields fields = resultReader.getAcroFields();

List<String> signatures = fields.getSignedFieldNames();
for (String signature : signatures) {
printSignatureDetails(fields, signature);
}
} catch (DocumentException | IOException e) {
System.err.println(e.getMessage());
}
}

private static void extractVerifiedCryptoSignature() {

System.out.println("Signature extraction");

PdfPKCS7.loadCacertsKeyStore();

try {
InputStream is = Signing.class.getResourceAsStream("/CryptoSignedSha256.pdf");
PdfReader reader = new PdfReader(is);
AcroFields fields = reader.getAcroFields();

List<String> signatures = fields.getSignedFieldNames();
for (String signature : signatures) {
printSignatureDetails(fields, signature);

PdfPKCS7 pk = fields.verifySignature(signature);

X509Certificate certificate = pk.getSigningCertificate();
X509Name subjectFields = PdfPKCS7.getSubjectFields(certificate);
System.out.println("Certificate subject fields: " + subjectFields);
System.out.println("Certificate verified: " + pk.verify());

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Date signed: " + sdf.format(pk.getSignDate().getTime()));
System.out.println("Timestamp verified: " + pk.verifyTimestampImprint());
}
} catch (SignatureException | IOException | NoSuchAlgorithmException e) {
System.err.println(e.getMessage());
}
}

private static void printSignatureDetails(AcroFields fields, String signature) {
System.out.println("Signature: " + signature);
System.out.println("Signature covers whole document: " + fields.signatureCoversWholeDocument(signature));
System.out.println("Revision: " + fields.getRevision(signature));
}
}
Binary file not shown.