diff options
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java')
-rw-r--r-- | pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java | 249 |
1 files changed, 232 insertions, 17 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java index d2a21518..c83d3bf7 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.io.OutputStream; import java.security.SignatureException; import java.util.ArrayList; +import java.util.Calendar; import java.util.List; import org.apache.pdfbox.cos.COSArray; @@ -34,6 +35,7 @@ import at.gv.egiz.pdfas.common.utils.StringUtils; import at.gv.egiz.pdfas.lib.api.Configuration; import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.StatusRequest; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; import at.gv.egiz.pdfas.lib.api.sign.SignResult; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; @@ -44,6 +46,9 @@ import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; import at.gv.egiz.pdfas.lib.impl.positioning.Positioning; import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner; import at.gv.egiz.pdfas.lib.impl.signing.PdfSignerFactory; +import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PdfboxSignerWrapper; +import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.SignatureDataExtractor; +import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.SignatureDataInjector; import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory; @@ -87,6 +92,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { RequestedSignature requestedSignature = new RequestedSignature( status); + + requestedSignature.setCertificate(status.getSignParamter() + .getPlainSigner().getCertificate()); + // Only use this profileID because validation was done in // RequestedSignature String signatureProfileID = requestedSignature @@ -168,8 +177,9 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { // TODO: Create signature IPdfSigner signer = PdfSignerFactory.createPdfSigner(); - signer.signPDF(status.getPdfObject(), requestedSignature, status - .getSignParamter().getPlainSigner()); + signer.signPDF(status.getPdfObject(), requestedSignature, + new PdfboxSignerWrapper(status.getSignParamter() + .getPlainSigner())); // status.getPdfObject().setSignedDocument(status.getPdfObject().getStampedDocument()); @@ -193,7 +203,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { } } - public List<VerifyResult> verify(VerifyParameter parameter) throws PdfAsException { + public List<VerifyResult> verify(VerifyParameter parameter) + throws PdfAsException { try { List<VerifyResult> result = new ArrayList<VerifyResult>(); ISettings settings = (ISettings) parameter.getConfiguration(); @@ -216,30 +227,29 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { COSBase base = field.getDictionaryObject("V"); COSDictionary dict = (COSDictionary) base; - logger.debug("Signer: " - + dict.getNameAsString("Name")); + logger.debug("Signer: " + dict.getNameAsString("Name")); logger.debug("SubFilter: " + dict.getNameAsString("SubFilter")); - logger.debug("Filter: " - + dict.getNameAsString("Filter")); + logger.debug("Filter: " + dict.getNameAsString("Filter")); logger.debug("Modified: " + dict.getNameAsString("M")); COSArray byteRange = (COSArray) dict .getDictionaryObject("ByteRange"); - StringBuilder sb = new StringBuilder(); int[] bytes = new int[byteRange.size()]; for (int j = 0; j < byteRange.size(); j++) { bytes[j] = byteRange.getInt(j); sb.append(" " + bytes[j]); } - + logger.debug("ByteRange" + sb.toString()); COSString content = (COSString) dict .getDictionaryObject("Contents"); - /*logger.trace("Content: " - + StringUtils.bytesToHexString(content.getBytes()));*/ + /* + * logger.trace("Content: " + + * StringUtils.bytesToHexString(content.getBytes())); + */ ByteArrayOutputStream contentData = new ByteArrayOutputStream(); for (int j = 0; j < bytes.length; j = j + 2) { @@ -250,12 +260,13 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { } contentData.close(); - IVerifyFilter verifyFilter = - verifier.getVerifier(dict.getNameAsString("Filter"), dict.getNameAsString("SubFilter")); + IVerifyFilter verifyFilter = verifier.getVerifier( + dict.getNameAsString("Filter"), + dict.getNameAsString("SubFilter")); + + List<VerifyResult> results = verifyFilter.verify( + contentData.toByteArray(), content.getBytes()); - List<VerifyResult> results = - verifyFilter.verify(contentData.toByteArray(), content.getBytes()); - result.addAll(results); } return result; @@ -265,7 +276,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { } catch (PdfAsException e) { // TODO Auto-generated catch block e.printStackTrace(); - } + } throw new PdfAsException(); } @@ -273,4 +284,208 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { return new ConfigurationImpl(this.settings); } + public StatusRequest startSign(SignParameter parameter) + throws PdfAsException { + // TODO: VERIFY PARAMETERS + StatusRequestImpl request = new StatusRequestImpl(); + + try { + // Status initialization + if (!(parameter.getConfiguration() instanceof ISettings)) { + throw new PdfAsSettingsException("Invalid settings object!"); + } + + ISettings settings = (ISettings) parameter.getConfiguration(); + OperationStatus status = new OperationStatus(settings, parameter); + + RequestedSignature requestedSignature = new RequestedSignature( + status); + + status.setRequestedSignature(requestedSignature); + + request.setStatus(status); + + request.setNeedCertificate(true); + + return request; + } catch (Throwable e) { + logger.error("startSign", e); + throw new PdfAsException("startSign", e); + } + } + + public StatusRequest process(StatusRequest statusRequest) + throws PdfAsException { + if (!(statusRequest instanceof StatusRequestImpl)) { + throw new PdfAsException("Invalid Status"); + } + + StatusRequestImpl request = (StatusRequestImpl) statusRequest; + OperationStatus status = request.getStatus(); + + if (request.needCertificate()) { + try { + status.getRequestedSignature().setCertificate( + request.getCertificate()); + + // set Original PDF Document Data + status.getPdfObject().setOriginalDocument( + status.getSignParamter().getDataSource().getByteData()); + + // STAMPER! + stampPdf(status); + request.setNeedCertificate(false); + + status.setSigningDate(Calendar.getInstance()); + + // GET Signature DATA + String pdfFilter = status.getSignParamter().getPlainSigner() + .getPDFFilter(); + String pdfSubFilter = status.getSignParamter().getPlainSigner() + .getPDFSubFilter(); + SignatureDataExtractor signatureDataExtractor = new SignatureDataExtractor( + request.getCertificate(), pdfFilter, pdfSubFilter, status.getSigningDate()); + + IPdfSigner signer = PdfSignerFactory.createPdfSigner(); + signer.signPDF(status.getPdfObject(), + status.getRequestedSignature(), signatureDataExtractor); + request.setSignatureData(signatureDataExtractor + .getSignatureData()); + request.setByteRange(signatureDataExtractor.getByteRange()); + request.setNeedSignature(true); + + } catch (Throwable e) { + logger.error("process", e); + throw new PdfAsException("process", e); + } + } else if (request.needSignature()) { + request.setNeedSignature(false); + // TODO: Inject signature byte[] into signedDocument + int offset = request.getSignatureData().length; + + for(int i = 0; i < request.getSignature().length; i++) { + status.getPdfObject().getSignedDocument()[offset + i] = request.getSignature()[i]; + } + /* + + String pdfFilter = status.getSignParamter().getPlainSigner() + .getPDFFilter(); + String pdfSubFilter = status.getSignParamter().getPlainSigner() + .getPDFSubFilter(); + SignatureDataInjector injector = new SignatureDataInjector( + request.getCertificate(), pdfFilter, pdfSubFilter, status.getSigningDate(), + request.getSignature(), request.getSignatureData()); + + IPdfSigner signer = PdfSignerFactory.createPdfSigner(); + signer.signPDF(status.getPdfObject(), + status.getRequestedSignature(), injector);*/ + request.setIsReady(true); + } else { + throw new PdfAsException("Invalid Status"); + } + + return request; + } + + public SignResult finishSign(StatusRequest statusRequest) + throws PdfAsException { + if (!(statusRequest instanceof StatusRequestImpl)) { + throw new PdfAsException("Invalid Status"); + } + + StatusRequestImpl request = (StatusRequestImpl) statusRequest; + OperationStatus status = request.getStatus(); + + if (!request.isReady()) { + throw new PdfAsException("Invalid Status"); + } + + try { + return createSignResult(status); + } catch(IOException e) { + throw new PdfAsException("Invalid Status", e); + } + } + + private void stampPdf(OperationStatus status) throws PdfAsException, + IOException { + + RequestedSignature requestedSignature = status.getRequestedSignature(); + String signatureProfileID = requestedSignature.getSignatureProfileID(); + SignatureProfileConfiguration signatureProfileConfiguration = status + .getSignatureProfileConfiguration(signatureProfileID); + + if (requestedSignature.isVisual()) { + logger.info("Creating visual siganture block"); + // ================================================================ + // SignBlockCreationStage (visual) -> create visual signature + // block (logicaly) + SignatureProfileSettings signatureProfileSettings = TableFactory + .createProfile(signatureProfileID, settings); + + Table main = TableFactory.createSigTable(signatureProfileSettings, + MAIN, settings, requestedSignature); + + IPDFStamper stamper = StamperFactory.createDefaultStamper(settings); + IPDFVisualObject visualObject = stamper.createVisualPDFObject( + status.getPdfObject(), main); + + // ================================================================ + // PositioningStage (visual) -> find position or use fixed + // position + + String posString = status.getSignParamter().getSignaturePosition(); + + if (posString == null) { + posString = signatureProfileConfiguration + .getDefaultPositioning(); + } + + TablePos tablePos = null; + + if (posString == null) { + tablePos = new TablePos(); + } else { + tablePos = new TablePos(posString); + } + + PDDocument originalDocument = PDDocument + .load(new ByteArrayInputStream(status.getPdfObject() + .getOriginalDocument())); + + PositioningInstruction positioningInstruction = Positioning + .determineTablePositioning(tablePos, "", originalDocument, + visualObject); + + // ================================================================ + // StampingStage (visual) -> stamp logical signature block to + // location (itext) + + byte[] incrementalUpdate = stamper.writeVisualObject(visualObject, + positioningInstruction, status.getPdfObject() + .getOriginalDocument()); + status.getPdfObject().setStampedDocument(incrementalUpdate); + } else { + logger.info("No visual siganture block"); + // Stamped Object is equal to original + status.getPdfObject().setStampedDocument( + status.getPdfObject().getOriginalDocument()); + } + } + + private SignResult createSignResult(OperationStatus status) throws IOException { + // ================================================================ + // Create SignResult + SignResultImpl result = new SignResultImpl(status.getSignParamter() + .getOutput()); + OutputStream outputStream = result.getOutputDocument() + .createOutputStream(); + + outputStream.write(status.getPdfObject().getSignedDocument()); + + outputStream.close(); + + return result; + } + } |