View Javadoc

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  		//Signature format
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  		// setCrypto (PrivateKey,Certificate[],CRL[],PdfName)
80  		// sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
81  		//TODO : insert CRLs in PDF Signature here
82  		sap.setCrypto(userpkandcert.getPrivateKey(), userpkandcert.getX509CertificateChain(), null, filter);
83  		
84  		// Informations 
85  		sap.setReason(pdfsignatureparams.getReason());
86  		sap.setLocation(pdfsignatureparams.getLocation());
87  		
88  		//Document certification
89  		sap.setCertificationLevel(pdfsignatureparams.getDocCert());
90  		
91  		//	 comment next line to have an invisible signature
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 					//sig_pic.scalePercent(scale);
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 				//Getting Image Instance
117 			    //sap.setContact(pdfsignatureparams.);
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 			//keep original pdf file, will be deleted at end
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 			//original=signed, so moving original to temporary file, and then delete it
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 }