From 62434d4f7d4bf80b4c236c4153bffab703916ee3 Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Thu, 3 Oct 2013 13:38:33 +0200 Subject: no callback API implemted --- .../main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java | 4 + .../at/gv/egiz/pdfas/lib/api/StatusRequest.java | 16 ++ .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java | 249 +++++++++++++++++++-- .../gv/egiz/pdfas/lib/impl/StatusRequestImpl.java | 87 +++++++ .../gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java | 4 +- .../lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 11 +- .../impl/signing/pdfbox/PdfboxSignerWrapper.java | 36 ++- .../sig_interface/PDFASSignatureInterface.java | 13 ++ .../sig_interface/SignatureDataExtractor.java | 70 ++++++ .../sig_interface/SignatureDataInjector.java | 48 ++++ .../pdfas/lib/impl/status/OperationStatus.java | 32 ++- .../pdfas/lib/impl/status/RequestedSignature.java | 5 +- 12 files changed, 545 insertions(+), 30 deletions(-) create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/StatusRequest.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/StatusRequestImpl.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java (limited to 'pdf-as-lib/src') diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java index 92b2001a..76e760bd 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java @@ -37,4 +37,8 @@ public interface PdfAs { * @return A private copy of the pdf as configuration */ public Configuration getConfiguration(); + + public StatusRequest startSign(SignParameter parameter) throws PdfAsException; + public StatusRequest process(StatusRequest statusRequest) throws PdfAsException; + public SignResult finishSign(StatusRequest statusRequest) throws PdfAsException; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/StatusRequest.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/StatusRequest.java new file mode 100644 index 00000000..fb6ceb44 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/StatusRequest.java @@ -0,0 +1,16 @@ +package at.gv.egiz.pdfas.lib.api; + +import java.security.cert.CertificateException; + +public interface StatusRequest { + + public boolean needCertificate(); + public boolean needSignature(); + public boolean isReady(); + + public byte[] getSignatureData(); + public int[] getSignatureDataByteRange(); + public void setCertificate(byte[] encodedCertificate) throws CertificateException; + public void setSigature(byte[] signatureValue) ; + +} 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 verify(VerifyParameter parameter) throws PdfAsException { + public List verify(VerifyParameter parameter) + throws PdfAsException { try { List result = new ArrayList(); 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 results = verifyFilter.verify( + contentData.toByteArray(), content.getBytes()); - List 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; + } + } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/StatusRequestImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/StatusRequestImpl.java new file mode 100644 index 00000000..3b2f62f7 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/StatusRequestImpl.java @@ -0,0 +1,87 @@ +package at.gv.egiz.pdfas.lib.impl; + +import iaik.x509.X509Certificate; + +import java.security.cert.CertificateException; + +import at.gv.egiz.pdfas.lib.api.StatusRequest; +import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; + +public class StatusRequestImpl implements StatusRequest { + + private boolean needCertificate = false; + private boolean needSignature = false; + private boolean isReady = false; + private X509Certificate certificate; + private byte[] encodedSignature; + private byte[] signatureData; + private int[] byteRange; + + private OperationStatus status; + + public OperationStatus getStatus() { + return status; + } + + public void setStatus(OperationStatus status) { + this.status = status; + } + + public void setSignatureData(byte[] signatureData) { + this.signatureData = signatureData; + } + + public void setByteRange(int[] byteRange) { + this.byteRange = byteRange; + } + + public X509Certificate getCertificate() { + return this.certificate; + } + + public byte[] getSignature() { + return this.encodedSignature; + } + + public void setNeedSignature(boolean value) { + this.needSignature = value; + } + + public void setNeedCertificate(boolean value) { + this.needCertificate = value; + } + + public boolean needCertificate() { + return needCertificate; + } + + public boolean needSignature() { + return needSignature; + } + + public boolean isReady() { + return isReady; + } + + public void setIsReady(boolean value) { + this.isReady = value; + } + + public byte[] getSignatureData() { + // TODO Auto-generated method stub + return signatureData; + } + + public int[] getSignatureDataByteRange() { + // TODO Auto-generated method stub + return byteRange; + } + + public void setCertificate(byte[] encodedCertificate) throws CertificateException { + this.certificate = new X509Certificate(encodedCertificate); + } + + public void setSigature(byte[] signatureValue) { + this.encodedSignature = signatureValue; + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java index 8ff3a276..38c6530a 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java @@ -1,12 +1,12 @@ package at.gv.egiz.pdfas.lib.impl.signing; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; +import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; import at.gv.egiz.pdfas.lib.impl.status.PDFObject; import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; public interface IPdfSigner { void signPDF(PDFObject pdfObject, - RequestedSignature requestedSignature, IPlainSigner signer) throws PdfAsException; + RequestedSignature requestedSignature, PDFASSignatureInterface signer) throws PdfAsException; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index 7f16a87a..3f566f06 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -24,6 +24,7 @@ import at.gv.egiz.pdfas.common.utils.StreamUtils; import at.gv.egiz.pdfas.common.utils.TempFileHelper; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner; +import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver; import at.gv.egiz.pdfas.lib.impl.status.PDFObject; @@ -33,7 +34,8 @@ public class PADESPDFBOXSigner implements IPdfSigner { private static final Logger logger = LoggerFactory.getLogger(PADESPDFBOXSigner.class); - public void signPDF(PDFObject pdfObject, RequestedSignature requestedSignature, IPlainSigner signer) + public void signPDF(PDFObject pdfObject, RequestedSignature requestedSignature, + PDFASSignatureInterface signer) throws PdfAsException { String fisTmpFile = null; @@ -70,10 +72,13 @@ public class PADESPDFBOXSigner implements IPdfSigner { signature.setReason("PDF-AS Signatur"); + logger.debug("Signing @ " + signer.getSigningDate().getTime().toString()); // the signing date, needed for valid signature - signature.setSignDate(Calendar.getInstance()); + signature.setSignDate(signer.getSigningDate()); - doc.addSignature(signature, new PdfboxSignerWrapper(signer, signature)); + signer.setPDSignature(signature); + + doc.addSignature(signature, signer); // pdfbox patched (FIS -> IS) doc.saveIncremental(fis, fos); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java index fb629dd6..91734312 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java @@ -3,35 +3,59 @@ package at.gv.egiz.pdfas.lib.impl.signing.pdfbox; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Calendar; import org.apache.pdfbox.exceptions.SignatureException; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.utils.StreamUtils; import at.gv.egiz.pdfas.common.utils.StringUtils; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; +import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; -public class PdfboxSignerWrapper implements SignatureInterface { +public class PdfboxSignerWrapper implements PDFASSignatureInterface { private static final Logger logger = LoggerFactory.getLogger(PdfboxSignerWrapper.class); private IPlainSigner signer; private PDSignature signature; - - public PdfboxSignerWrapper(IPlainSigner signer, PDSignature signature) { + private int[] byteRange; + private Calendar date; + + public PdfboxSignerWrapper(IPlainSigner signer) { this.signer = signer; - this.signature = signature; + this.date = Calendar.getInstance(); } public byte[] sign(InputStream inputStream) throws SignatureException, IOException { - byte[] signature = signer.sign(StreamUtils.inputStreamToByteArray(inputStream)); + byteRange = this.signature.getByteRange(); + byte[] signature = signer.sign(StreamUtils.inputStreamToByteArray(inputStream)); logger.debug("Signature Data: " + StringUtils.bytesToHexString(signature)); FileOutputStream fos = new FileOutputStream("/tmp/fos.bin"); fos.write(signature); fos.close(); return signature; } + + public int[] getByteRange() { + return byteRange; + } + + public String getPDFSubFilter() { + return this.signer.getPDFSubFilter(); + } + + public String getPDFFilter() { + return this.signer.getPDFFilter(); + } + + public void setPDSignature(PDSignature signature) { + this.signature = signature; + } + + public Calendar getSigningDate() { + return this.date; + } } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java new file mode 100644 index 00000000..43f0014d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; + +import java.util.Calendar; + +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; + +public interface PDFASSignatureInterface extends SignatureInterface { + public String getPDFSubFilter(); + public String getPDFFilter(); + public void setPDSignature(PDSignature signature); + public Calendar getSigningDate(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java new file mode 100644 index 00000000..4b7afa6c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java @@ -0,0 +1,70 @@ +package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; + +import iaik.x509.X509Certificate; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Calendar; + +import org.apache.pdfbox.exceptions.SignatureException; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; + +import at.gv.egiz.pdfas.common.utils.StreamUtils; + +public class SignatureDataExtractor implements PDFASSignatureInterface { + + protected X509Certificate certificate; + protected byte[] signatureData; + + protected String pdfSubFilter; + protected String pdfFilter; + protected PDSignature signature; + protected int[] byteRange; + protected Calendar date; + + public SignatureDataExtractor(X509Certificate certificate, + String filter, String subfilter, Calendar date) { + this.certificate = certificate; + this.pdfFilter = filter; + this.pdfSubFilter = subfilter; + this.date = date; + } + + public X509Certificate getCertificate() { + return certificate; + } + + public String getPDFSubFilter() { + return this.pdfSubFilter; + } + + public String getPDFFilter() { + return this.pdfFilter; + } + + public byte[] getSignatureData() { + return this.signatureData; + } + + public byte[] sign(InputStream content) throws SignatureException, + IOException { + signatureData = StreamUtils.inputStreamToByteArray(content); + byteRange = this.signature.getByteRange(); + return new byte[] { 0 }; + } + + public void setPDSignature(PDSignature signature) { + this.signature = signature; + } + + public int[] getByteRange() { + return byteRange; + } + + public Calendar getSigningDate() { + return this.date; + } + + + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java new file mode 100644 index 00000000..65083a36 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java @@ -0,0 +1,48 @@ +package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; + +import iaik.x509.X509Certificate; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Calendar; + +import org.apache.pdfbox.exceptions.SignatureException; + +import at.gv.egiz.pdfas.common.utils.StreamUtils; + +public class SignatureDataInjector extends SignatureDataExtractor { + + protected byte[] signature; + protected byte[] oldSignatureData; + + public SignatureDataInjector(X509Certificate certificate, String filter, + String subfilter, Calendar date, byte[] signature, byte[] signatureData) { + super(certificate, filter, subfilter, date); + this.signature = signature; + this.oldSignatureData = signatureData; + } + + @Override + public byte[] sign(InputStream content) throws SignatureException, + IOException { + byte[] signatureData = StreamUtils.inputStreamToByteArray(content); + + FileOutputStream fos2 = new FileOutputStream("/home/afitzek/devel/pdfas_neu/sign2.pdf"); + fos2.write(signatureData); + fos2.close(); + + if(signatureData.length != this.oldSignatureData.length) { + throw new SignatureException("Signature Data missmatch!"); + } + + for(int i = 0; i < signatureData.length; i++) { + if(signatureData[i] != this.oldSignatureData[i]) { + throw new SignatureException("Signature Data missmatch! " + i + " " + signatureData[i] + " vs " + this.oldSignatureData[i]); + } + } + + return signature; + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java index a9fd1443..2f7b67e7 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java @@ -1,5 +1,7 @@ package at.gv.egiz.pdfas.lib.impl.status; +import java.io.Serializable; +import java.util.Calendar; import java.util.HashMap; import java.util.Map; @@ -10,7 +12,13 @@ import at.gv.egiz.pdfas.lib.impl.configuration.GlobalConfiguration; import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; -public class OperationStatus { +public class OperationStatus implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -2985007198666388528L; + private SignParameter signParamter; private PDFObject pdfObject = new PDFObject(this); @@ -21,6 +29,8 @@ public class OperationStatus { private Map signatureProfiles = new HashMap(); private TempFileHelper helper; + private RequestedSignature requestedSignature; + private Calendar signingDate; public OperationStatus(ISettings configuration, SignParameter signParameter) { this.configuration = configuration; @@ -33,8 +43,18 @@ public class OperationStatus { super.finalize(); } + + // ======================================================================== + public RequestedSignature getRequestedSignature() { + return requestedSignature; + } + + public void setRequestedSignature(RequestedSignature requestedSignature) { + this.requestedSignature = requestedSignature; + } + public PlaceholderConfiguration getPlaceholderConfiguration() { if(this.placeholderConfiguration == null) { this.placeholderConfiguration = @@ -87,4 +107,14 @@ public class OperationStatus { public ISettings getSettings() { return this.configuration; } + + public Calendar getSigningDate() { + return signingDate; + } + + public void setSigningDate(Calendar signingDate) { + this.signingDate = signingDate; + } + + } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java index a2a6acd8..a1820104 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java @@ -26,7 +26,6 @@ public class RequestedSignature { throw new PdfAsSettingsException("Failed to determine Signature Profile!"); } } - certificate = status.getSignParamter().getPlainSigner().getCertificate(); this.signatureProfile = profileID; @@ -53,4 +52,8 @@ public class RequestedSignature { return this.certificate; } + public void setCertificate(X509Certificate certificate) { + this.certificate = certificate; + } + } -- cgit v1.2.3