aboutsummaryrefslogtreecommitdiff
path: root/signature-standards/sigs-pkcs7detached
diff options
context:
space:
mode:
Diffstat (limited to 'signature-standards/sigs-pkcs7detached')
-rw-r--r--signature-standards/sigs-pkcs7detached/.gitignore1
-rw-r--r--signature-standards/sigs-pkcs7detached/build.gradle37
-rw-r--r--signature-standards/sigs-pkcs7detached/src/main/java/META-INF/MANIFEST.MF3
-rw-r--r--signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java176
-rw-r--r--signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java118
-rw-r--r--signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/package-info.java8
6 files changed, 343 insertions, 0 deletions
diff --git a/signature-standards/sigs-pkcs7detached/.gitignore b/signature-standards/sigs-pkcs7detached/.gitignore
new file mode 100644
index 00000000..5e56e040
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/signature-standards/sigs-pkcs7detached/build.gradle b/signature-standards/sigs-pkcs7detached/build.gradle
new file mode 100644
index 00000000..d1ea063f
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/build.gradle
@@ -0,0 +1,37 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'Signature Standard PKCS7 Detached', 'Implementation-Version': version
+ }
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ compile project (':pdf-as-lib')
+ compile project (':pdf-as-common')
+ compile group: 'iaik', name: 'iaik_cms', version: '4.1'
+ compile group: 'eu.europa.ec.joinup.egovlabs.pdf-as.iaik', name: 'iaik_jce_eval_signed', version: '4.0'
+ compile group: 'eu.europa.ec.joinup.egovlabs.pdf-as.iaik', name: 'iaik_ecc_eval_signed', version: '2.19'
+ compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
+ compile group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'
+ compile group: 'org.bouncycastle', name: 'bcmail-jdk16', version: '1.46'
+ testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+test {
+ systemProperties 'property': 'value'
+}
+
+uploadArchives {
+ repositories {
+ flatDir {
+ dirs 'repos'
+ }
+ }
+}
diff --git a/signature-standards/sigs-pkcs7detached/src/main/java/META-INF/MANIFEST.MF b/signature-standards/sigs-pkcs7detached/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..5e949512
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java
new file mode 100644
index 00000000..83df6a59
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java
@@ -0,0 +1,176 @@
+package at.gv.egiz.pdfas.sigs.pkcs7detached;
+
+import iaik.asn1.ASN1Object;
+import iaik.asn1.ObjectID;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.asn1.structures.Attribute;
+import iaik.asn1.structures.ChoiceOfTime;
+import iaik.cms.ContentInfo;
+import iaik.cms.IssuerAndSerialNumber;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.cms.Utils;
+import iaik.pkcs.PKCSException;
+import iaik.pkcs.pkcs7.Data;
+import iaik.security.ecc.provider.ECCProvider;
+import iaik.security.provider.IAIK;
+import iaik.x509.X509Certificate;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.util.Date;
+
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSProcessable;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
+import at.gv.egiz.pdfas.common.utils.StringUtils;
+import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
+
+public class PKCS7DetachedSigner implements IPlainSigner {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(PKCS7DetachedSigner.class);
+
+ PrivateKey privKey;
+ X509Certificate cert;
+
+ public PKCS7DetachedSigner(String file, String alias, String kspassword,
+ String keypassword, String type) throws PdfAsException {
+ try {
+ IAIK.addAsProvider();
+ 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;
+ }
+
+ class CMSProcessableInputStream implements CMSProcessable {
+
+ InputStream in;
+
+ public CMSProcessableInputStream(InputStream is) {
+ in = is;
+ }
+
+ public Object getContent() {
+ return null;
+ }
+
+ public void write(OutputStream out) throws IOException, CMSException {
+ // read the content only one time
+ byte[] buffer = new byte[8 * 1024];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ out.write(buffer, 0, read);
+ }
+ in.close();
+ }
+ }
+
+ private static BouncyCastleProvider provider = new BouncyCastleProvider();
+
+ /*
+ * public byte[] sign(byte[] input, int[] byteRange) throws PdfAsException {
+ * CMSProcessableInputStream content = new CMSProcessableInputStream(new
+ * ByteArrayInputStream(input)); CMSSignedDataGenerator gen = new
+ * CMSSignedDataGenerator(); // CertificateChain List<X509Certificate>
+ * certList = Arrays.asList(cert);
+ *
+ * CertStore certStore = null; try { certStore =
+ * CertStore.getInstance("Collection", new
+ * CollectionCertStoreParameters(certList), provider);
+ * gen.addSigner(privKey, (X509Certificate)certList.get(0),
+ * CMSSignedGenerator.DIGEST_SHA256); gen.addCertificatesAndCRLs(certStore);
+ * CMSSignedData signedData = gen.generate(content, false, provider); return
+ * signedData.getEncoded(); } catch (Exception e) { // should be handled
+ * e.printStackTrace(); } throw new
+ * RuntimeException("Problem while preparing signature"); }
+ */
+
+ public byte[] sign(byte[] input, int[] byteRange) throws PdfAsException {
+ 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
+ // }
+ // }
+ // SubjectKeyID subjectKeyId = new SubjectKeyID(cert);
+ IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert);
+ SignerInfo signer1 = new SignerInfo(issuer, AlgorithmID.sha256,
+ AlgorithmID.ecdsa_plain_With_SHA256,
+ privKey);
+
+ SignedData si = new SignedData(input, SignedData.EXPLICIT);
+ si.addCertificates(new Certificate[] { cert });
+ Attribute signingTime = new Attribute(ObjectID.signingTime,
+ new ASN1Object[] { new ChoiceOfTime(new Date())
+ .toASN1Object() });
+ Attribute contentType = new Attribute(ObjectID.contentType, new ASN1Object[] {
+ new ObjectID("1.2.840.113549.1.7.1")
+ });
+ // Attribute signingCert = new
+ // Attribute(ObjectID.signingCertificateV2,
+ // new ASN1Object[] { cert.toASN1Object() });
+
+ Attribute[] attributes = new Attribute[] { signingTime, contentType };
+ signer1.setSignedAttributes(attributes);
+ si.addSignerInfo(signer1);
+ InputStream dataIs = si.getInputStream();
+ byte[] buf = new byte[1024];
+ int r;
+ while ((r = dataIs.read(buf)) > 0)
+ ; // skip data
+ ContentInfo ci = new ContentInfo(si);
+
+ return ci.getEncoded();
+ } catch (NoSuchAlgorithmException e) {
+ throw new PdfAsSignatureException("", e);
+ } catch (iaik.cms.CMSException e) {
+ throw new PdfAsSignatureException("", e);
+ } catch (IOException e) {
+ throw new PdfAsSignatureException("", e);
+ }
+ }
+
+ public String getPDFSubFilter() {
+ return PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED.getName();
+ }
+
+ public String getPDFFilter() {
+ return PDSignature.FILTER_ADOBE_PPKLITE.getName();
+ }
+
+}
diff --git a/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
new file mode 100644
index 00000000..ed7ae01c
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
@@ -0,0 +1,118 @@
+package at.gv.egiz.pdfas.sigs.pkcs7detached;
+
+import iaik.asn1.ObjectID;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.cms.ContentInfo;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.security.ecc.provider.ECCProvider;
+import iaik.security.provider.IAIK;
+import iaik.x509.X509Certificate;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.security.SignatureException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
+import at.gv.egiz.pdfas.lib.impl.verify.FilterEntry;
+import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter;
+import at.gv.egiz.pdfas.lib.impl.verify.SignatureCheckImpl;
+import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl;
+
+public class PKCS7DetachedVerifier implements IVerifyFilter {
+
+ private static final Logger logger = LoggerFactory.getLogger(PKCS7DetachedVerifier.class);
+
+ public PKCS7DetachedVerifier() {
+ IAIK.addAsProvider();
+ ECCProvider.addAsProvider();
+ }
+
+ public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent)
+ throws PdfAsException {
+ try {
+ List<VerifyResult> result = new ArrayList<VerifyResult>();
+
+ SignedData signedData = new SignedData(contentData, new AlgorithmID[] {
+ AlgorithmID.sha256
+ });
+
+ FileOutputStream fos = new FileOutputStream("/tmp/verify.bin");
+ fos.write(signatureContent);
+ fos.close();
+
+ ContentInfo ci = new ContentInfo(new ByteArrayInputStream(
+ signatureContent));
+ if (!ci.getContentType().equals(ObjectID.cms_signedData)) {
+ throw new PdfAsException("No Signed DATA");
+ }
+ //SignedData signedData = (SignedData)ci.getContent();
+ //signedData.setContent(contentData);
+
+ signedData.decode(ci.getContentInputStream());
+
+ // get the signer infos
+ SignerInfo[] signerInfos = signedData.getSignerInfos();
+ // verify the signatures
+ for (int i = 0; i < signerInfos.length; i++) {
+ VerifyResultImpl verifyResult = new VerifyResultImpl();
+ verifyResult.setSignatureData(contentData);
+ try {
+ // verify the signature for SignerInfo at index i
+ X509Certificate signer_cert = signedData.verify(i);
+ // if the signature is OK the certificate of the
+ // signer is returned
+ logger.info("Signature OK from signer: "
+ + signer_cert.getSubjectDN());
+ verifyResult.setSignerCertificate(signer_cert);
+ verifyResult.setValueCheckCode(new SignatureCheckImpl(0, "OK"));
+ verifyResult.setManifestCheckCode(new SignatureCheckImpl(99, "not checked"));
+ verifyResult.setCertificateCheck(new SignatureCheckImpl(99, "not checked"));
+ verifyResult.setVerificationDone(true);
+ } catch (SignatureException ex) {
+ // if the signature is not OK a SignatureException
+ // is thrown
+ logger.info("Signature ERROR from signer: "
+ + signedData.getCertificate(
+ signerInfos[i].getSignerIdentifier())
+ .getSubjectDN(), ex);
+
+ verifyResult.setSignerCertificate(
+ signedData.getCertificate(signerInfos[i].getSignerIdentifier()));
+ verifyResult.setValueCheckCode(new SignatureCheckImpl(1, "failed to check signature"));
+ verifyResult.setManifestCheckCode(new SignatureCheckImpl(99, "not checked"));
+ verifyResult.setCertificateCheck(new SignatureCheckImpl(99, "not checked"));
+ verifyResult.setVerificationDone(false);
+ verifyResult.setVerificationException(new PdfAsSignatureException("failed to check signature", ex));
+ }
+ result.add(verifyResult);
+ }
+
+ return result;
+ } catch (Throwable e) {
+ throw new PdfAsException("Verify failed", e);
+ }
+ }
+
+ public List<FilterEntry> getFiters() {
+ List<FilterEntry> result = new ArrayList<FilterEntry>();
+ result.add(new FilterEntry(PDSignature.FILTER_ADOBE_PPKLITE, PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED));
+ //result.add(new FilterEntry(PDSignature.FILTER_ADOBE_PPKLITE, PDSignature.SUBFILTER_ETSI_CADES_DETACHED));
+ return result;
+ }
+
+ public void setConfiguration(Configuration config) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/package-info.java b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/package-info.java
new file mode 100644
index 00000000..69a99830
--- /dev/null
+++ b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.sigs.pkcs7detached; \ No newline at end of file