aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java18
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java2
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BaseSLConnector.java7
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java59
-rw-r--r--signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java1
-rw-r--r--signature-standards/sigs-pcks7detached/build.gradle2
-rw-r--r--signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java146
-rw-r--r--signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java28
8 files changed, 214 insertions, 49 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 ed029aac..3c4cc223 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
@@ -29,8 +29,8 @@ public class DeveloperMain {
public static final String keyStoreFile = "/home/afitzek/devel/pdfas_neu/test.p12";
public static final String keyStoreType = "PKCS12";
public static final String keyStorePass = "123456";
- //public static final String keyAlias = "pdf";
- public static final String keyAlias = "ecc_test";
+ public static final String keyAlias = "pdf";
+ //public static final String keyAlias = "ecc_test";
public static final String keyPass = "123456";
public static void main(String[] args) {
@@ -44,13 +44,13 @@ public class DeveloperMain {
data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/qr_2.pdf"));
SignParameter parameter = PdfAsFactory.createSignParameter(config, new ByteArrayDataSource(data));
ByteArrayDataSink bads = new ByteArrayDataSink();
- parameter.setSignatureProfileId("SIGNATURBLOCK_DE_PDFA");
+ parameter.setSignatureProfileId("SIGNATURBLOCK_DE");
parameter.setOutput(bads);
- //parameter.setPlainSigner(new PAdESSigner(new BKUSLConnector(config)));
- parameter.setPlainSigner(signer);
+ parameter.setPlainSigner(new PAdESSigner(new BKUSLConnector(config)));
+ //parameter.setPlainSigner(signer);
//parameter.setPlainSigner(new PAdESSigner(new MOAConnector(config)));
-
- /*StatusRequest request = pdfas.startSign(parameter);
+ /*
+ StatusRequest request = pdfas.startSign(parameter);
if(request.needCertificate()) {
request.setCertificate(signer.getCertificate().getEncoded());
@@ -82,8 +82,8 @@ public class DeveloperMain {
fos.write(bads.getData());
fos.close();
- //VerifyParameter verify = new VerifyParameterImpl(config, new ByteArrayDataSource(bads.getData()));
- //pdfas.verify(verify);
+ VerifyParameter verify = new VerifyParameterImpl(config, new ByteArrayDataSource(bads.getData()));
+ pdfas.verify(verify);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
index deecae21..414f2854 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
@@ -130,7 +130,7 @@ public class BKUSLConnector extends BaseSLConnector {
try {
slRequest = SLMarschaller.marshalToString(of
.createCreateCMSSignatureRequest(request));
- logger.debug(slRequest);
+ //logger.debug(slRequest);
String slResponse = performHttpRequestToBKU(slRequest);
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BaseSLConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BaseSLConnector.java
index e5abc6bd..5a03bbef 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BaseSLConnector.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BaseSLConnector.java
@@ -59,7 +59,7 @@ public abstract class BaseSLConnector implements ISLConnector {
int currentdataOff = 0;
Arrays.fill(data, (byte)0);
-
+ int[] exclude_range = new int[byteRange.length-2];
for(int i = 0; i < byteRange.length; i = i + 2) {
int offset = byteRange[i];
int size = byteRange[i+1];
@@ -68,7 +68,10 @@ public abstract class BaseSLConnector implements ISLConnector {
data[offset + j] = signatureData[currentdataOff];
currentdataOff++;
}
-
+ if(i + 2 < byteRange.length) {
+ exclude_range[i] = offset + size; // exclude offset
+ exclude_range[i+1] = byteRange[i+2]; // exclude size
+ }
}
// == MetaInfoType
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
index 8a7950a4..3a998816 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
@@ -1,11 +1,19 @@
package at.gv.egiz.sl.util;
+import java.io.ByteArrayInputStream;
+import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.util.Iterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
import iaik.x509.X509Certificate;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
+import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl;
import at.gv.egiz.sl.CreateCMSSignatureRequestType;
import at.gv.egiz.sl.CreateCMSSignatureResponseType;
import at.gv.egiz.sl.InfoboxAssocArrayPairType;
@@ -14,12 +22,15 @@ import at.gv.egiz.sl.InfoboxReadResponseType;
public class ISignatureConnectorSLWrapper implements ISignatureConnector {
+ private static final Logger logger = LoggerFactory
+ .getLogger(ISignatureConnectorSLWrapper.class);
+
private ISLConnector connector;
-
+
public ISignatureConnectorSLWrapper(ISLConnector connector) {
this.connector = connector;
}
-
+
public X509Certificate getCertificate() throws PdfAsException {
X509Certificate certificate = null;
try {
@@ -47,9 +58,47 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector {
}
public byte[] sign(byte[] input, int[] byteRange) throws PdfAsException {
- CreateCMSSignatureRequestType request = connector.createCMSRequest(input, byteRange);
- CreateCMSSignatureResponseType response = connector.sendCMSRequest(request);
-
+ CreateCMSSignatureRequestType request = connector.createCMSRequest(
+ input, byteRange);
+ CreateCMSSignatureResponseType response = connector
+ .sendCMSRequest(request);
+ try {
+ SignedData signedData = new SignedData(new ByteArrayInputStream(
+ response.getCMSSignature()));
+
+ signedData.setContent(input);
+
+ // get the signer infos
+ SignerInfo[] signerInfos = signedData.getSignerInfos();
+ // verify the signatures
+ for (int i = 0; i < signerInfos.length; i++) {
+ VerifyResultImpl verifyResult = new VerifyResultImpl();
+ 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);
+ } 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());
+
+ verifyResult.setSignerCertificate(signedData
+ .getCertificate(signerInfos[i]
+ .getSignerIdentifier()));
+ }
+ }
+ } catch (Exception e) {
+ logger.error("ERROR", e);
+ }
+
return response.getCMSSignature();
}
diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java
index 7fc0081b..6945d9b3 100644
--- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java
+++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java
@@ -32,6 +32,7 @@ public class PAdESSigner implements IPlainSigner {
public String getPDFSubFilter() {
return PDSignature.SUBFILTER_ETSI_CADES_DETACHED.getName();
+ //return PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED.getName();
}
public String getPDFFilter() {
diff --git a/signature-standards/sigs-pcks7detached/build.gradle b/signature-standards/sigs-pcks7detached/build.gradle
index 6864bc00..d1ea063f 100644
--- a/signature-standards/sigs-pcks7detached/build.gradle
+++ b/signature-standards/sigs-pcks7detached/build.gradle
@@ -19,6 +19,8 @@ dependencies {
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.+'
}
diff --git a/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java
index 25b42f5f..4c4b3621 100644
--- a/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java
+++ b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java
@@ -1,40 +1,54 @@
package at.gv.egiz.pdfas.sigs.pkcs7detached;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.ObjectID;
import iaik.asn1.structures.AlgorithmID;
-import iaik.cms.SignedDataStream;
+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.SubjectKeyID;
+import iaik.cms.Utils;
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.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.PDFIOException;
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.getInstance();
+ IAIK.addAsProvider();
ECCProvider.addAsProvider();
KeyStore ks = KeyStore.getInstance(type);
ks.load(new FileInputStream(file), kspassword.toCharArray());
@@ -49,40 +63,114 @@ public class PKCS7DetachedSigner implements IPlainSigner {
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
- }
+ // 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);
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA256", "IAIK");
+ md.update(input);
+ byte[] sha256 = md.digest();
+ logger.info("Message digest: " + StringUtils.bytesToHexString(sha256));
+ } catch (Exception e) {
+ e.printStackTrace();
}
- signed_data_stream.writeTo(baos);
- return baos.toByteArray();
+ IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert);
+ SignerInfo signer1 = new SignerInfo(issuer, AlgorithmID.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 signingCert = new
+ // Attribute(ObjectID.signingCertificateV2,
+ // new ASN1Object[] { cert.toASN1Object() });
+
+ Attribute[] attributes = new Attribute[] { signingTime };
+ 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 (X509ExtensionException e) {
+ } catch (iaik.cms.CMSException e) {
+ throw new PdfAsSignatureException("", e);
+ } catch (IOException e) {
throw new PdfAsSignatureException("", e);
- } catch (IOException e) {
- throw new PDFIOException("", 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-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
index 7e974f3f..e8f0661b 100644
--- a/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
+++ b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
@@ -1,10 +1,14 @@
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.x509.X509Certificate;
import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.List;
@@ -24,21 +28,38 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
private static final Logger logger = LoggerFactory.getLogger(PKCS7DetachedVerifier.class);
+ public PKCS7DetachedVerifier() {
+ }
+
public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent)
throws PdfAsException {
try {
List<VerifyResult> result = new ArrayList<VerifyResult>();
- SignedData signedData = new SignedData(new ByteArrayInputStream(
+
+ 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));
- signedData.setContent(contentData);
+ 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();
try {
-
// verify the signature for SignerInfo at index i
X509Certificate signer_cert = signedData.verify(i);
// if the signature is OK the certificate of the
@@ -69,6 +90,7 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
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;
}