diff options
| author | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-11-19 08:51:11 +0100 | 
|---|---|---|
| committer | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-11-19 09:05:45 +0100 | 
| commit | ee9277cb68ce97fee9dc788a38f83ec40cab3c7e (patch) | |
| tree | 527d308e426a86d70d781ff3f6fd0f092385a285 /pdf-as-pdfbox/src/main | |
| parent | e6450f35edb106a9898d454e2d90ded3bef1a786 (diff) | |
| download | pdf-as-4-ee9277cb68ce97fee9dc788a38f83ec40cab3c7e.tar.gz pdf-as-4-ee9277cb68ce97fee9dc788a38f83ec40cab3c7e.tar.bz2 pdf-as-4-ee9277cb68ce97fee9dc788a38f83ec40cab3c7e.zip | |
mutlithreading GC problem fixed, visual signature options finalizing, would destroy resource buffer, which are used during save incremental update
Conflicts:
	pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
Diffstat (limited to 'pdf-as-pdfbox/src/main')
| -rw-r--r-- | pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 219 | 
1 files changed, 82 insertions, 137 deletions
| diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index b0de9c3d..8556ae9f 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -23,8 +23,6 @@   ******************************************************************************/  package at.gv.egiz.pdfas.lib.impl.signing.pdfbox; -import iaik.x509.X509Certificate; -  import java.awt.Graphics2D;  import java.awt.Image;  import java.awt.image.BufferedImage; @@ -36,17 +34,15 @@ import java.io.IOException;  import java.io.InputStream;  import java.util.ArrayList;  import java.util.Calendar; -import java.util.Iterator;  import java.util.List;  import org.apache.commons.io.IOUtils;  import org.apache.pdfbox.cos.COSArray;  import org.apache.pdfbox.cos.COSBase;  import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.cos.COSDocument;  import org.apache.pdfbox.cos.COSInteger;  import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.cos.COSObject; -import org.apache.pdfbox.cos.COSStream;  import org.apache.pdfbox.cos.COSString;  import org.apache.pdfbox.exceptions.COSVisitorException;  import org.apache.pdfbox.exceptions.SignatureException; @@ -103,18 +99,19 @@ import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;  import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;  import at.knowcenter.wag.egov.egiz.pdf.TablePos;  import at.knowcenter.wag.egov.egiz.table.Table; +import iaik.x509.X509Certificate;  public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  	private static final Logger logger = LoggerFactory  			.getLogger(PADESPDFBOXSigner.class); - +	  	public void signPDF(PDFObject genericPdfObject,  			RequestedSignature requestedSignature,  			PDFASSignatureInterface genericSigner) throws PdfAsException {  		String fisTmpFile = null; -		PDFAsVisualSignatureProperties properties = null; +		PDFAsVisualSignatureProperties properties=null;  		if (!(genericPdfObject instanceof PDFBOXObject)) {  			// tODO: @@ -132,6 +129,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  		TempFileHelper helper = pdfObject.getStatus().getTempFileHelper();  		PDDocument doc = null; +		SignatureOptions options = new SignatureOptions(); +		COSDocument visualSignatureDocumentGuard = null;  		try {  			fisTmpFile = helper.getStaticFilename(); @@ -149,7 +148,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				}  				doc = pdfObject.getDocument(); - +				  				SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter  						.checkPlaceholderSignature(pdfObject.getStatus(),  								pdfObject.getStatus().getSettings()); @@ -163,8 +162,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  						logger.debug("Placeholder Profile set to: "  								+ signaturePlaceholderData.getProfile());  						requestedSignature -								.setSignatureProfileID(signaturePlaceholderData -										.getProfile()); +						.setSignatureProfileID(signaturePlaceholderData +								.getProfile());  					}  					tablePos = signaturePlaceholderData.getTablePos(); @@ -209,7 +208,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				// signature.setSignDate(signer.getSigningDate());  				signer.setPDSignature(signature); -				SignatureOptions options = new SignatureOptions(); +				  				options.setPreferedSignatureSize(0x1000);  				// Is visible Signature @@ -324,8 +323,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  					requestedSignature.setSignaturePosition(position); -					properties = new PDFAsVisualSignatureProperties(pdfObject -							.getStatus().getSettings(), pdfObject, +					properties = new PDFAsVisualSignatureProperties( +							pdfObject.getStatus().getSettings(), pdfObject,  							(PdfBoxVisualObject) visualObject,  							positioningInstruction, signatureProfileSettings); @@ -359,7 +358,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  							logger.info("Placeholder name: "  									+ signaturePlaceholderData -											.getPlaceholderName()); +									.getPlaceholderName());  							COSDictionary xobjectsDictionary = (COSDictionary) page  									.findResources().getCOSDictionary()  									.getDictionaryObject(COSName.XOBJECT); @@ -367,10 +366,10 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  									.getPlaceholderName(), img);  							xobjectsDictionary.setNeedToBeUpdate(true);  							page.findResources().getCOSObject() -									.setNeedToBeUpdate(true); +							.setNeedToBeUpdate(true);  							logger.info("Placeholder name: "  									+ signaturePlaceholderData -											.getPlaceholderName()); +									.getPlaceholderName());  						} finally {  							IOUtils.closeQuietly(is);  						} @@ -380,51 +379,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  						PDDocumentCatalog root = doc.getDocumentCatalog();  						COSBase base = root.getCOSDictionary().getItem(  								COSName.OUTPUT_INTENTS); - -						boolean sRGBFound = false; - -						/* -						if (base != null) { -							if (base instanceof COSArray) { -								List<PDOutputIntent> outputIntents = root -										.getOutputIntent(); -								Iterator<PDOutputIntent> outputIterator = outputIntents -										.iterator(); -								while (outputIterator.hasNext()) { -									PDOutputIntent ouputIntent = outputIterator -											.next(); -									if ("sRGB IEC61966-2.1".equals(ouputIntent -											.getInfo())) { -										sRGBFound = true; -										break; -									} -								} -							} else if (base instanceof COSObject && ((COSObject)base).getObject() instanceof COSArray) { -									COSArray array = (COSArray)((COSObject)base).getObject(); -									Iterator<COSBase> cosIterator = array.iterator(); -									while(cosIterator.hasNext()) { -										COSBase oiBase = cosIterator.next(); -										PDOutputIntent oi = new PDOutputIntent((COSDictionary) oiBase); -										if ("sRGB IEC61966-2.1".equals(oi -												.getInfo())) { -											sRGBFound = true; -											break; -										} -									} -							} else { -								try { -									PDOutputIntent oi = new PDOutputIntent((COSDictionary) base); -									if ("sRGB IEC61966-2.1".equals(oi -											.getInfo())) { -										sRGBFound = true; -									} -								} catch(Throwable e){  -									logger.warn("Failed to check existing Output Intent in PDF-A document"); -								} -							} -						}*/ - -						if (!sRGBFound) { +						if (base == null) {  							InputStream colorProfile = null;  							try {  								colorProfile = PDDocumentCatalog.class @@ -437,26 +392,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  									oi.setOutputCondition("sRGB IEC61966-2.1");  									oi.setOutputConditionIdentifier("sRGB IEC61966-2.1");  									oi.setRegistryName("http://www.color.org"); -									List<PDOutputIntent> intents = new ArrayList<PDOutputIntent>(); -									intents.add(oi); -									root.setOutputIntents(intents); -									/*if (base != null) { -										if (base instanceof COSObject && ((COSObject)base).getObject() instanceof COSArray) { -											COSArray array = (COSArray)((COSObject)base).getObject(); -											array.clear(); -											array.add(oi); -											array.setNeedToBeUpdate(true); -										} else if (!(base instanceof COSArray)) { -											// Need to convert Output Intent from base object to array -											//PDOutputIntent existingOI = new PDOutputIntent((COSDictionary)base); -											COSArray array = new COSArray(); -											//array.add(existingOI); -											array.add(oi); -								            root.getCOSDictionary().setItem(COSName.OUTPUT_INTENTS, array); -										} -									} else { -										root.addOutputIntent(oi); -									}*/ + +									root.addOutputIntent(oi);  									root.getCOSObject().setNeedToBeUpdate(true);  									logger.info("added Output Intent");  								} catch (Throwable e) { @@ -470,9 +407,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  						}  					} + +  					options.setPage(positioningInstruction.getPage());  					options.setVisualSignature(properties.getVisibleSignature());  				} +				 +				visualSignatureDocumentGuard = options.getVisualSignature();  				doc.addSignature(signature, signer, options); @@ -489,18 +430,18 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm(); -				// PDStructureTreeRoot pdstRoot = -				// doc.getDocumentCatalog().getStructureTreeRoot(); -				// COSDictionary dic = -				// doc.getDocumentCatalog().getCOSDictionary(); -				// PDStructureElement el = new PDStructureElement("Widget", -				// pdstRoot); +				//				PDStructureTreeRoot pdstRoot = doc.getDocumentCatalog().getStructureTreeRoot(); +				//				COSDictionary dic = doc.getDocumentCatalog().getCOSDictionary(); +				//				PDStructureElement el = new PDStructureElement("Widget", pdstRoot); + +  				PDSignatureField signatureField = null;  				if (acroFormm != null) {  					@SuppressWarnings("unchecked")  					List<PDField> fields = acroFormm.getFields(); +  					if (fields != null) {  						for (PDField pdField : fields) {  							if (pdField != null) { @@ -509,7 +450,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  									if (tmpSigField.getSignature() != null  											&& tmpSigField.getSignature() -													.getDictionary() != null) { +											.getDictionary() != null) {  										if (tmpSigField  												.getSignature()  												.getDictionary() @@ -527,12 +468,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  					}  					if (signatureField != null) { -						signatureField.setPartialName(sigFieldName); +						signatureField.setPartialName(sigFieldName);	  					} -					if (properties != null) { -						signatureField.setAlternateFieldName(properties -								.getAlternativeTableCaption()); -					} else { +					if(properties!=null){ +						signatureField.setAlternateFieldName(properties.getAlternativeTableCaption()); +					}else{  						signatureField.setAlternateFieldName(sigFieldName);  					}  				} else { @@ -541,37 +481,35 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				// PDF-UA  				logger.info("Adding pdf/ua content."); -				try { +				try{  					PDDocumentCatalog root = doc.getDocumentCatalog();  					PDStructureTreeRoot treeRoot = root.getStructureTreeRoot(); - +					if(treeRoot != null) {  					logger.info("Tree Root: {}", treeRoot.toString());  					List<Object> kids = treeRoot.getKids(); -					if (kids == null) { +					if(kids==null){  						logger.info("No kid-elements in structure tree Root, maybe not PDF/UA document");  					}  					PDStructureElement docElement = null; -					for (Object k : kids) { -						if (k instanceof PDStructureElement) { -							docElement = (PDStructureElement) k; +					for(Object k: kids){ +						if(k instanceof PDStructureElement){ +							docElement=(PDStructureElement) k;  							break; -							// if(((PDStructureElement) -							// k).getStructureType().equals("Document")){ -							// docElement=(PDStructureElement) k; -							// } +							//	if(((PDStructureElement) k).getStructureType().equals("Document")){ +							//		docElement=(PDStructureElement) k; +							//	}  						}  					}  					PDStructureElement sigBlock = new PDStructureElement(  							"Form", docElement); -					// create object dictionary and add as child element -					COSDictionary objectdic = new COSDictionary(); +					//create object dictionary and add as child element +					COSDictionary objectdic= new COSDictionary();  					objectdic.setName("Type", "OBJR"); -					objectdic.setItem("Pg", signatureField.getWidget() -							.getPage()); +					objectdic.setItem("Pg", signatureField.getWidget().getPage());  					objectdic.setItem("Obj", signatureField.getWidget());  					List<Object> l = new ArrayList<Object>(); @@ -582,10 +520,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  					sigBlock.setParent(docElement);  					docElement.appendKid(sigBlock); -					// Create and add Attribute dictionary to mitigate PAC -					// warning -					COSDictionary sigBlockDic = (COSDictionary) sigBlock -							.getCOSObject(); +					//Create and add Attribute dictionary to mitigate PAC warning +					COSDictionary sigBlockDic = (COSDictionary) sigBlock.getCOSObject();  					COSDictionary sub = new COSDictionary();  					sub.setName("O", "Layout"); @@ -593,31 +529,30 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  					sigBlockDic.setItem(COSName.A, sub);  					sigBlockDic.setNeedToBeUpdate(true); -					// Modify number tree + +					//Modify number tree  					PDNumberTreeNode ntn = treeRoot.getParentTree(); -					if (ntn == null) { +					if(ntn==null){  						ntn = new PDNumberTreeNode(objectdic, null);  						logger.info("No number-tree-node found!");  					} -					COSDictionary ntndic = ntn.getCOSDictionary(); -					COSArray ntndicnumbersarray = (COSArray) ntndic -							.getDictionaryObject(COSName.NUMS); +					COSDictionary ntndic=ntn.getCOSDictionary(); +					COSArray ntndicnumbersarray = (COSArray)ntndic.getDictionaryObject(COSName.NUMS);  					int arrindex = ntndicnumbersarray.size(); -					int treeindex = arrindex / 2; +					int treeindex = arrindex/2;  					ntndicnumbersarray.add(arrindex, COSInteger.get(treeindex)); -					ntndicnumbersarray.add(arrindex + 1, -							sigBlock.getCOSObject()); +					ntndicnumbersarray.add(arrindex+1, sigBlock.getCOSObject());  					treeRoot.setParentTree(ntn); -					treeRoot.setParentTreeNextKey(treeindex + 1); +					treeRoot.setParentTreeNextKey(treeindex+1); -					// setStructureParent -					PDAnnotationWidget widg = signatureField.getWidget(); +					//setStructureParent +					PDAnnotationWidget widg=signatureField.getWidget();  					widg.setStructParent(treeindex); -					// add the Tabs /S Element for Tabbing through annots +					//add the Tabs /S Element for Tabbing through annots  					PDPage p = signatureField.getWidget().getPage();  					p.getCOSDictionary().setName("Tabs", "S");  					p.getCOSObject().setNeedToBeUpdate(true); @@ -628,11 +563,12 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  					objectdic.getCOSObject().setNeedToBeUpdate(true);  					docElement.getCOSObject().setNeedToBeUpdate(true); -				} catch (Throwable e) { -					if (signatureProfileSettings.isPDFUA() == true) { +					} +				}catch(Throwable e){ +					if (signatureProfileSettings.isPDFUA()==true){  						logger.error("Could not create PDF-UA conform document!");  						throw new PdfAsException("error.pdf.sig.pdfua.1", e); -					} else { +					}else{  						logger.info("Could not create PDF-UA conform signature");  					}  				} @@ -682,11 +618,17 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				try {  					tmpFileIs = new FileInputStream(new File(fisTmpFile)); - -					doc.saveIncremental(tmpFileIs, tmpOutputStream); +					synchronized (doc) { +						doc.saveIncremental(tmpFileIs, tmpOutputStream); +					}  					tmpFileIs.close();  				} finally {  					IOUtils.closeQuietly(tmpFileIs); +					if(options != null) { +						if(options.getVisualSignature() != null) { +							options.getVisualSignature().close(); +						} +					}  				}  				tmpOutputStream.flush();  				tmpOutputStream.close(); @@ -729,7 +671,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				}  			} -			if (fisTmpFile != null) { +			if(fisTmpFile != null) {  				helper.deleteFile(fisTmpFile);  			}  			logger.debug("Signature done!"); @@ -778,7 +720,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  	public Image generateVisibleSignaturePreview(SignParameter parameter,  			java.security.cert.X509Certificate cert, int resolution,  			OperationStatus status, RequestedSignature requestedSignature) -			throws PDFASError { +					throws PDFASError {  		try {  			PDFBOXObject pdfObject = (PDFBOXObject) status.getPdfObject(); @@ -834,12 +776,15 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  			PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(  					pdfObject.getStatus().getSettings(), pdfObject, -					(PdfBoxVisualObject) visualObject, positioningInstruction, +					(PdfBoxVisualObject) visualObject, positioningInstruction,   					signatureProfileSettings);  			properties.buildSignature(); -			PDDocument visualDoc = PDDocument.load(properties +			PDDocument visualDoc; +			synchronized (PDDocument.class) { +				visualDoc = PDDocument.load(properties  					.getVisibleSignature()); +			}  			// PDPageable pageable = new PDPageable(visualDoc);  			List<PDPage> pages = new ArrayList<PDPage>();  			visualDoc.getDocumentCatalog().getPages().getAllKids(pages); @@ -862,11 +807,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  			graphics.drawImage(outputImage, 0, 0, cutOut.getWidth(), cutOut  					.getHeight(), (int) (1 * factor), (int) (outputImage -					.getHeight() - ((position.getHeight() + 1) * factor)), -					(int) ((1 + position.getWidth()) * factor), -					(int) (outputImage.getHeight() -							- ((position.getHeight() + 1) * factor) + (position -							.getHeight() * factor)), null); +							.getHeight() - ((position.getHeight() + 1) * factor)), +							(int) ((1 + position.getWidth()) * factor), +							(int) (outputImage.getHeight() +									- ((position.getHeight() + 1) * factor) + (position +											.getHeight() * factor)), null);  			return cutOut;  		} catch (PdfAsException e) {  			logger.warn("PDF-AS  Exception", e); | 
