1 package org.eparapher.core.signature;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.net.MalformedURLException;
8
9 import org.apache.log4j.Logger;
10 import org.eparapher.core.EParapherManager;
11 import org.eparapher.core.crypto.EPKeystoreManager;
12 import org.eparapher.core.crypto.keystore.IUserKeystore;
13 import org.eparapher.core.tools.PDFConverterWrapper;
14
15 import com.lowagie.text.BadElementException;
16 import com.lowagie.text.DocumentException;
17 import com.lowagie.text.Image;
18 import com.lowagie.text.Rectangle;
19 import com.lowagie.text.pdf.PdfName;
20 import com.lowagie.text.pdf.PdfReader;
21 import com.lowagie.text.pdf.PdfSignatureAppearance;
22 import com.lowagie.text.pdf.PdfStamper;
23
24 public class PDFSigner {
25
26 private static Logger log = Logger.getLogger(PDFSigner.class);
27
28 private IUserKeystore userpkandcert;
29
30 private String original_pdf_file;
31 private String signed_pdf_file;
32
33 private boolean converted;
34
35 public PDFSigner() {
36 userpkandcert = EPKeystoreManager.getInstance().getUserkeystore();
37 }
38
39 public void sign(String moriginal_pdf, PDFSignatureParameters pdfsignatureparams, boolean pdf_just_converted) {
40
41 converted = pdf_just_converted;
42 original_pdf_file = moriginal_pdf;
43 signed_pdf_file = "";
44 String originalAlias = userpkandcert.getDefaultAlias();
45 if (pdfsignatureparams.getSignatureAlias()!=null &&
46 userpkandcert.containsAlias(pdfsignatureparams.getSignatureAlias()) )
47 userpkandcert.setDefaultAlias(pdfsignatureparams.getSignatureAlias());
48
49 managePDFFileBeforeSignature();
50 FileOutputStream signed_pdf_fos = getSignedFileOutputStream();
51
52 PdfReader reader = null;
53 try {
54 reader = new PdfReader(original_pdf_file);
55 } catch (IOException e) {
56 String msg = "Cannot open PDF "+original_pdf_file+" file with iText APIs : " + e.getLocalizedMessage();
57 EParapherManager.getInstance().getUI().errorMessage(msg,e);
58 log.error(msg, e);
59 }
60
61
62 PdfName filter = pdfsignatureparams.getFormat();
63
64 log.debug("Generating signature for '"+original_pdf_file+"'");
65
66 PdfStamper stp = null;
67 try {
68 stp = PdfStamper.createSignature(reader, signed_pdf_fos, '\0', null, pdfsignatureparams.isMultipleSignature());
69 } catch (DocumentException e) {
70 String msg = "Cannot create PDF signature for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
71 EParapherManager.getInstance().getUI().errorMessage(msg,e);
72 log.error(msg, e);
73 } catch (IOException e) {
74 String msg = "Cannot create PDF signature for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
75 EParapherManager.getInstance().getUI().errorMessage(msg,e);
76 log.error(msg, e);
77 }
78 PdfSignatureAppearance sap = stp.getSignatureAppearance();
79
80
81
82 sap.setCrypto(userpkandcert.getPrivateKey(), userpkandcert.getX509CertificateChain(), null, filter);
83
84
85 sap.setReason(pdfsignatureparams.getReason());
86 sap.setLocation(pdfsignatureparams.getLocation());
87
88
89 sap.setCertificationLevel(pdfsignatureparams.getDocCert());
90
91
92 if (pdfsignatureparams.isVisibleSignature()) {
93
94 try {
95 Image sig_pic = Image.getInstance(pdfsignatureparams.getVisibleSignatureFile());
96 sap.setAcro6Layers(true);
97 sap.setImage(sig_pic);
98
99 Rectangle r;
100 if (pdfsignatureparams.getVisibleSignatureLowerLeftX() < 0 ||
101 pdfsignatureparams.getVisibleSignatureLowerLeftY() < 0) {
102
103 int x = pdfsignatureparams.getVisibleSignatureUpperRightX();
104 int y = pdfsignatureparams.getVisibleSignatureUpperRightY();
105 float scale = pdfsignatureparams.getVisibleSignatureScale()/100;
106
107 float llx = x-sig_pic.getWidth()*scale;
108 float lly = y-sig_pic.getHeight()*scale;
109 r = new Rectangle( llx,lly, x, y);
110 } else
111 r = new Rectangle( pdfsignatureparams.getVisibleSignatureLowerLeftX(),
112 pdfsignatureparams.getVisibleSignatureLowerLeftY(),
113 pdfsignatureparams.getVisibleSignatureUpperRightX(),
114 pdfsignatureparams.getVisibleSignatureUpperRightY());
115 sap.setVisibleSignature(r, pdfsignatureparams.getVisibleSignaturePage(), null);
116
117
118 } catch (BadElementException e) {
119 String msg = "Cannot insert the PDF visible signature ("+pdfsignatureparams.getVisibleSignatureFile()+") for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
120 EParapherManager.getInstance().getUI().errorMessage(msg,e);
121 log.error(msg, e);
122 } catch (MalformedURLException e) {
123 String msg = "Cannot insert the PDF visible signature ("+pdfsignatureparams.getVisibleSignatureFile()+") for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
124 EParapherManager.getInstance().getUI().errorMessage(msg,e);
125 log.error(msg, e);
126 } catch (IOException e) {
127 String msg = "Cannot insert the PDF visible signature ("+pdfsignatureparams.getVisibleSignatureFile()+") for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
128 EParapherManager.getInstance().getUI().errorMessage(msg,e);
129 log.error(msg, e);
130 }
131 }
132
133 try {
134 stp.close();
135 managePDFFilesAfterSignature();
136 log.info("PDF digital signature applied on "+signed_pdf_file);
137 } catch (DocumentException e) {
138 String msg = "Cannot finalise the PDF signature for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
139 EParapherManager.getInstance().getUI().errorMessage(msg,e);
140 log.error(msg, e);
141 } catch (IOException e) {
142 String msg = "Cannot finalise the PDF signature for "+original_pdf_file+" with iText APIs : " + e.getLocalizedMessage();
143 EParapherManager.getInstance().getUI().errorMessage(msg,e);
144 log.error(msg, e);
145 }
146
147 userpkandcert.setDefaultAlias(originalAlias);
148 }
149
150 private void managePDFFilesAfterSignature() {
151 File original = new File(original_pdf_file);
152 if ( converted || (EParapherManager.getInstance().getSettings().isPDFSignatureReplaceFile() && !converted) ) {
153 original.delete();
154 }
155 }
156
157 private void managePDFFileBeforeSignature() {
158
159 String new_original_file = "";
160 if (converted) {
161
162 int pos = original_pdf_file.lastIndexOf(PDFConverterWrapper.PDF_TEMP_CONVERTED_FILE);
163 signed_pdf_file = original_pdf_file.substring(0, pos) + ".pdf";
164 }
165 if (EParapherManager.getInstance().getSettings().isPDFSignatureReplaceFile() && !converted) {
166
167 signed_pdf_file = original_pdf_file;
168 new_original_file = original_pdf_file + ".temp";
169 File file2move = new File(original_pdf_file);
170 if ( file2move.renameTo(new File(new_original_file)) )
171 original_pdf_file = new_original_file;
172 else {
173 String msg = " Couldn't write temporary file to " + file2move.getParent() + ".\r\n Please check your filesystem rights.";
174 EParapherManager.getInstance().getUI().errorMessage(msg);
175 log.error(msg);
176 }
177 }
178 if (!EParapherManager.getInstance().getSettings().isPDFSignatureReplaceFile() && !converted) {
179 int pos = original_pdf_file.toLowerCase().lastIndexOf(".pdf");
180 signed_pdf_file = original_pdf_file.substring(0,pos) + EParapherManager.getInstance().getSettings().getPDFSignatureNewFileNameAppend() + ".pdf";
181 }
182 }
183
184 private FileOutputStream getSignedFileOutputStream() {
185
186 FileOutputStream fos = null;
187 try {
188 fos = new FileOutputStream( signed_pdf_file );
189 } catch (FileNotFoundException e) {
190 String msg = " Couldn't write file " + signed_pdf_file + ".\r\n Please check your filesystem rights.";
191 EParapherManager.getInstance().getUI().errorMessage(msg,e);
192 log.error(msg, e);
193 }
194 return fos;
195 }
196
197 }