aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing')
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java12
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java9
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java141
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java37
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/JKSSigner.java78
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/package-info.java8
8 files changed, 301 insertions, 0 deletions
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
new file mode 100644
index 00000000..8ff3a276
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java
@@ -0,0 +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.status.PDFObject;
+import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+
+public interface IPdfSigner {
+
+ void signPDF(PDFObject pdfObject,
+ RequestedSignature requestedSignature, IPlainSigner signer) throws PdfAsException;
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java
new file mode 100644
index 00000000..469ea174
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java
@@ -0,0 +1,9 @@
+package at.gv.egiz.pdfas.lib.impl.signing;
+
+import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PADESPDFBOXSigner;
+
+public class PdfSignerFactory {
+ public static IPdfSigner createPdfSigner() {
+ return new PADESPDFBOXSigner();
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/package-info.java
new file mode 100644
index 00000000..6a59486b
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.signing; \ No newline at end of file
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
new file mode 100644
index 00000000..82ee57fe
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
@@ -0,0 +1,141 @@
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Calendar;
+
+import org.apache.pdfbox.exceptions.COSVisitorException;
+import org.apache.pdfbox.exceptions.SignatureException;
+import org.apache.pdfbox.pdmodel.PDDocument;
+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.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.messages.MessageResolver;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+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.stamping.TableFactory;
+import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
+import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+
+public class PADESPDFBOXSigner implements IPdfSigner {
+
+ private static final Logger logger = LoggerFactory.getLogger(PADESPDFBOXSigner.class);
+
+ public void signPDF(PDFObject pdfObject, RequestedSignature requestedSignature, IPlainSigner signer)
+ throws PdfAsException {
+ String fisTmpFile = null;
+
+ TempFileHelper helper = pdfObject.getStatus().getTempFileHelper();
+
+ try {
+ fisTmpFile = helper.getStaticFilename();
+
+ // write to temporary file
+ FileOutputStream fos = new FileOutputStream(new File(fisTmpFile));
+ fos.write(pdfObject.getStampedDocument());
+
+
+ FileInputStream fis = new FileInputStream(new File(fisTmpFile));
+
+ PDDocument doc = PDDocument.load(
+ new ByteArrayInputStream(pdfObject.getStampedDocument()));
+
+ PDSignature signature = new PDSignature();
+ signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); // default filter
+ signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED);
+
+ SignatureProfileSettings signatureProfileSettings = TableFactory
+ .createProfile(requestedSignature.getSignatureProfileID(),
+ pdfObject.getStatus().getSettings());
+
+ ValueResolver resolver = new ValueResolver();
+ String signerName = resolver.resolve("SIG_SUBJECT", signatureProfileSettings.getValue("SIG_SUBJECT"),
+ signatureProfileSettings, requestedSignature);
+ // TODO: change signature data from certificate
+ signature.setName(signerName);
+ //signature.setLocation("signer location");
+ signature.setReason("PDF-AS Signatur");
+
+
+ // the signing date, needed for valid signature
+ signature.setSignDate(Calendar.getInstance());
+
+ doc.addSignature(signature, new PdfboxSignerWrapper(signer, signature));
+
+ // pdfbox patched (FIS -> IS)
+ doc.saveIncremental(fis, fos);
+ fis.close();
+ fos.close();
+
+ fis = new FileInputStream(new File(fisTmpFile));
+
+ // write to resulting output stream
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(StreamUtils.inputStreamToByteArray(fis));
+ fis.close();
+ bos.close();
+
+ pdfObject.setSignedDocument(bos.toByteArray());
+
+ helper.deleteFile(fisTmpFile);
+
+ } catch (IOException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ } catch(SignatureException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ } catch (COSVisitorException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ }
+ }
+
+
+ public void signPDF(String src, String dst, SignatureInterface signer) throws Exception {
+ //ByteArrayOutputStream os = new ByteArrayOutputStream();
+ FileInputStream fis = new FileInputStream(new File(src));
+ FileOutputStream fos = new FileOutputStream(new File(dst));
+ byte[] buffer = new byte[8 * 1024];
+ byte[] outbuffer;
+ int c;
+ while ((c = fis.read(buffer)) != -1)
+ {
+ fos.write(buffer, 0, c);
+ }
+ fis.close();
+ PDDocument doc = PDDocument.load(src);
+ fis = new FileInputStream(new File(dst));
+
+ PDSignature signature = new PDSignature();
+ signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); // default filter
+
+ signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
+ signature.setName("Andraes Fitzek");
+ signature.setLocation("signer location");
+ signature.setReason("Test Signature");
+
+ // the signing date, needed for valid signature
+ signature.setSignDate(Calendar.getInstance());
+
+ doc.addSignature(signature, signer);
+
+ // pdfbox patched (FIS -> IS)
+ doc.saveIncremental(fis, fos);
+
+ fos.close();
+ // FileUtils.writeByteArrayToFile(new File(dst), os.toByteArray());
+ }
+
+}
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
new file mode 100644
index 00000000..fb629dd6
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java
@@ -0,0 +1,37 @@
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+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;
+
+public class PdfboxSignerWrapper implements SignatureInterface {
+
+ private static final Logger logger = LoggerFactory.getLogger(PdfboxSignerWrapper.class);
+
+ private IPlainSigner signer;
+ private PDSignature signature;
+
+ public PdfboxSignerWrapper(IPlainSigner signer, PDSignature signature) {
+ this.signer = signer;
+ this.signature = signature;
+ }
+
+ public byte[] sign(InputStream inputStream) throws SignatureException, IOException {
+ 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;
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/package-info.java
new file mode 100644
index 00000000..85b552f6
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/JKSSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/JKSSigner.java
new file mode 100644
index 00000000..85697436
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/JKSSigner.java
@@ -0,0 +1,78 @@
+package at.gv.egiz.pdfas.lib.impl.signing.sig_interface;
+
+import iaik.asn1.structures.AlgorithmID;
+import iaik.cms.SignedDataStream;
+import iaik.cms.SignerInfo;
+import iaik.cms.SubjectKeyID;
+import iaik.security.ecc.provider.ECCProvider;
+import iaik.security.provider.IAIK;
+import iaik.x509.X509Certificate;
+import iaik.x509.X509ExtensionException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+
+import org.apache.pdfbox.exceptions.SignatureException;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
+
+public class JKSSigner implements IPlainSigner {
+
+ PrivateKey privKey;
+ X509Certificate cert;
+
+ public JKSSigner(String file, String alias, String kspassword,
+ String keypassword, String type) throws PdfAsException {
+ try {
+ IAIK.getInstance();
+ ECCProvider.addAsProvider();
+ KeyStore ks = KeyStore.getInstance(type);
+ ks.load(new FileInputStream(file), kspassword.toCharArray());
+ privKey = (PrivateKey) ks.getKey(alias, keypassword.toCharArray());
+ cert = new X509Certificate(ks.getCertificate(alias).getEncoded());
+ } catch (Throwable e) {
+ throw new PdfAsException("Failed to get KeyStore", e);
+ }
+ }
+
+ public X509Certificate getCertificate() {
+ return cert;
+ }
+
+ public byte[] sign(byte[] input) throws SignatureException, IOException {
+ try {
+ SignedDataStream signed_data_stream = new SignedDataStream(
+ new ByteArrayInputStream(input), SignedDataStream.EXPLICIT);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ signed_data_stream.addCertificates(new Certificate[] { cert });
+
+ SubjectKeyID subjectKeyId = new SubjectKeyID(cert);
+ SignerInfo signer1 = new SignerInfo(subjectKeyId,
+ AlgorithmID.sha256, privKey);
+ signed_data_stream.addSignerInfo(signer1);
+ InputStream data_is = signed_data_stream.getInputStream();
+ if (signed_data_stream.getMode() == SignedDataStream.EXPLICIT) {
+ byte[] buf = new byte[1024];
+ int r;
+ while ((r = data_is.read(buf)) > 0) {
+ // do something useful
+ }
+ }
+ signed_data_stream.writeTo(baos);
+ return baos.toByteArray();
+ } catch (NoSuchAlgorithmException e) {
+ throw new SignatureException(e);
+ } catch (X509ExtensionException e) {
+ throw new SignatureException(e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/package-info.java
new file mode 100644
index 00000000..9f552662
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; \ No newline at end of file