aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2013-10-03 13:38:33 +0200
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2013-10-03 13:38:33 +0200
commit62434d4f7d4bf80b4c236c4153bffab703916ee3 (patch)
treed98ce0cd92e7e772e27d667a8b67cfcdc1d94db6
parentf076fe1f5f9c10b1f1c304956eb305987d48591a (diff)
downloadpdf-as-4-62434d4f7d4bf80b4c236c4153bffab703916ee3.tar.gz
pdf-as-4-62434d4f7d4bf80b4c236c4153bffab703916ee3.tar.bz2
pdf-as-4-62434d4f7d4bf80b4c236c4153bffab703916ee3.zip
no callback API implemted
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java32
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/StatusRequest.java16
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java249
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/StatusRequestImpl.java87
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java11
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java36
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java13
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java70
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java48
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java32
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java5
13 files changed, 577 insertions, 30 deletions
diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
index 0e114eae..8087da19 100644
--- a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
+++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
@@ -13,6 +13,7 @@ import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource;
import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.api.PdfAs;
import at.gv.egiz.pdfas.lib.api.PdfAsFactory;
+import at.gv.egiz.pdfas.lib.api.StatusRequest;
import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter;
@@ -42,6 +43,34 @@ public class DeveloperMain {
parameter.setSignatureProfileId("SIGNATURBLOCK_DE_NEU");
parameter.setOutput(bads);
parameter.setPlainSigner(signer);
+
+ StatusRequest request = pdfas.startSign(parameter);
+
+ if(request.needCertificate()) {
+ request.setCertificate(signer.getCertificate().getEncoded());
+ } else {
+ throw new Exception("Invalid status");
+ }
+
+ request = pdfas.process(request);
+
+ if(request.needSignature()) {
+ FileOutputStream fos2 = new FileOutputStream("/home/afitzek/devel/pdfas_neu/sign1.pdf");
+ fos2.write(request.getSignatureData());
+ fos2.close();
+ request.setSigature(signer.sign(request.getSignatureData()));
+ } else {
+ throw new Exception("Invalid status");
+ }
+
+ request = pdfas.process(request);
+
+ if(request.isReady()) {
+ pdfas.finishSign(request);
+ } else {
+ throw new Exception("Invalid status");
+ }
+
pdfas.sign(parameter);
FileOutputStream fos = new FileOutputStream("/home/afitzek/devel/pdfas_neu/simple_out.pdf");
fos.write(bads.getData());
@@ -59,6 +88,9 @@ public class DeveloperMain {
}catch (PdfAsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
}
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<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;
+ }
+
}
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<String, SignatureProfileConfiguration> signatureProfiles =
new HashMap<String, SignatureProfileConfiguration>();
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;
+ }
+
}