aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2013-11-28 12:33:02 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2013-11-28 12:33:02 +0100
commit5225b6852938c91940e0b491286583aa263f61d5 (patch)
tree78d236438c222046cedde0351dbb063c0d0740d2
parent7fdb06e32c43e99ec3599639348a3d758b9914a7 (diff)
downloadpdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.tar.gz
pdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.tar.bz2
pdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.zip
Verification with MOA SP working through PAdES Verifier
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java28
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java13
-rw-r--r--signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java133
-rw-r--r--signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java18
4 files changed, 140 insertions, 52 deletions
diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java
index 05fbbf67..dfd33c34 100644
--- a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java
+++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java
@@ -2,6 +2,7 @@ package at.gv.egiz.pdfas.cli;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
@@ -178,6 +179,12 @@ public class Main {
if (cli.hasOption(CLI_ARG_PROFILE_SHORT)) {
profilID = cli.getOptionValue(CLI_ARG_PROFILE_SHORT);
}
+
+ String outputFile = null;
+
+ if(cli.hasOption(CLI_ARG_OUTPUT_SHORT)) {
+ outputFile = cli.getOptionValue(CLI_ARG_OUTPUT_SHORT);
+ }
String pdfFile = null;
@@ -189,11 +196,21 @@ public class Main {
throw new Exception("Input file does not exists");
}
+ if(outputFile == null) {
+ if(pdfFile.endsWith(".pdf")) {
+ outputFile = pdfFile.subSequence(0, pdfFile.length() - ".pdf".length()) + "_signed.pdf";
+ } else {
+ outputFile = pdfFile + "_signed.pdf";
+ }
+ }
+
+ File outputPdfFile = new File(outputFile);
+
DataSource dataSource = new ByteArrayDataSource(
StreamUtils.inputStreamToByteArray(new FileInputStream(
inputFile)));
- DataSink dataSink = new ByteArrayDataSink();
+ ByteArrayDataSink dataSink = new ByteArrayDataSink();
PdfAs pdfAs = null;
@@ -214,8 +231,13 @@ public class Main {
// signParameter.setPlainSigner(signer);
SignResult result = pdfAs.sign(signParameter);
-
- // TODO write result to file
+
+ if(outputPdfFile.exists()) {
+ }
+
+ FileOutputStream fos = new FileOutputStream(outputPdfFile, false);
+ fos.write(dataSink.getData());
+ fos.close();
}
private static void perform_verify(CommandLine cli) throws Exception {
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java
index a7d4e80f..9a830097 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.Configuration;
public class VerifierDispatcher {
@@ -18,8 +19,9 @@ public class VerifierDispatcher {
.getLogger(VerifierDispatcher.class);
public static final String[] currentClasses = new String[] {
- "at.gv.egiz.pdfas.sigs.pkcs7detached.PKCS7DetachedVerifier"/*,
- "at.gv.egiz.pdfas.sigs.pades.PAdESVerifier"*/ };
+ "at.gv.egiz.pdfas.sigs.pkcs7detached.PKCS7DetachedVerifier",
+ // Uncomment to verify via MOA conncetor
+ "at.gv.egiz.pdfas.sigs.pades.PAdESVerifier" };
public Map<String, HashMap<String, IVerifyFilter>> filterMap = new HashMap<String, HashMap<String, IVerifyFilter>>();
@@ -30,8 +32,9 @@ public class VerifierDispatcher {
String clsName = currentClasses[i];
Class<? extends IVerifyFilter> cls = (Class<? extends IVerifyFilter>) Class
.forName(clsName);
- IVerifyFilter fitler = cls.newInstance();
- List<FilterEntry> entries = fitler.getFiters();
+ IVerifyFilter filter = cls.newInstance();
+ filter.setConfiguration((Configuration)settings);
+ List<FilterEntry> entries = filter.getFiters();
Iterator<FilterEntry> it = entries.iterator();
while (it.hasNext()) {
FilterEntry entry = it.next();
@@ -49,7 +52,7 @@ public class VerifierDispatcher {
throw new PdfAsException("Filter allready registered");
}
- filters.put(entry.getSubFilter().getName(), fitler);
+ filters.put(entry.getSubFilter().getName(), filter);
logger.debug("Registered Filter: " + cls.getName()
+ " for " + entry.getFilter().getName() + "/"
+ entry.getSubFilter().getName());
diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
index b1662d02..4af66e42 100644
--- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
+++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
@@ -12,6 +12,8 @@ import javax.xml.bind.JAXBElement;
import org.apache.axis2.databinding.types.Token;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import at.gv.egiz.dsig.X509DataType;
import at.gv.egiz.dsig.util.DsigMarschaller;
@@ -20,10 +22,13 @@ import at.gv.egiz.moa.SignatureVerificationServiceStub;
import at.gv.egiz.moa.SignatureVerificationServiceStub.CMSContentBaseType;
import at.gv.egiz.moa.SignatureVerificationServiceStub.CMSDataObjectOptionalMetaType;
import at.gv.egiz.moa.SignatureVerificationServiceStub.KeyInfoTypeChoice;
+import at.gv.egiz.moa.SignatureVerificationServiceStub.QualifiedCertificate;
import at.gv.egiz.moa.SignatureVerificationServiceStub.VerifyCMSSignatureRequest;
import at.gv.egiz.moa.SignatureVerificationServiceStub.VerifyCMSSignatureResponse;
import at.gv.egiz.moa.SignatureVerificationServiceStub.VerifyCMSSignatureResponseTypeSequence;
+import at.gv.egiz.moa.SignatureVerificationServiceStub.X509DataTypeSequence;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.utils.StreamUtils;
import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.api.verify.SignatureCheck;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
@@ -31,26 +36,33 @@ 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;
+import at.gv.egiz.sl.util.BKUSLConnector;
-public class PAdESVerifier implements IVerifyFilter {
+public class PAdESVerifier implements IVerifyFilter {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(PAdESVerifier.class);
private static final String MOA_VERIFY_URL = "moa.verify.url";
private static final String MOA_VERIFY_TRUSTPROFILE = "moa.verify.TrustProfileID";
-
+
private String moaEndpoint;
private String moaTrustProfile;
-
+
public PAdESVerifier() {
IAIK.getInstance();
ECCProvider.addAsProvider();
}
-
+
@SuppressWarnings("rawtypes")
public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent)
throws PdfAsException {
+
List<VerifyResult> resultList = new ArrayList<VerifyResult>();
try {
+ logger.info("verification with MOA @ " + this.moaEndpoint);
+
SignatureVerificationServiceStub service = new SignatureVerificationServiceStub(
this.moaEndpoint);
VerifyCMSSignatureRequest verifyCMSSignatureRequest = new VerifyCMSSignatureRequest();
@@ -71,59 +83,93 @@ public class PAdESVerifier implements IVerifyFilter {
verifyCMSSignatureRequest.setCMSSignature(cmsSignature);
verifyCMSSignatureRequest
.setDataObject(cmsDataObjectOptionalMetaType);
-
+
// cmsDataObjectOptionalMetaType.
VerifyCMSSignatureResponse response = service
.verifyCMSSignature(verifyCMSSignatureRequest);
-
- VerifyCMSSignatureResponseTypeSequence[] verifySequence = response.getVerifyCMSSignatureResponse().getVerifyCMSSignatureResponseTypeSequence();
- for(int i = 0 ; i < verifySequence.length; i++) {
+
+ VerifyCMSSignatureResponseTypeSequence[] verifySequence = response
+ .getVerifyCMSSignatureResponse()
+ .getVerifyCMSSignatureResponseTypeSequence();
+ for (int i = 0; i < verifySequence.length; i++) {
VerifyResultImpl result = new VerifyResultImpl();
-
+
SignatureCheck certificateCheck;
-
- verifySequence[i].getSignerInfo().getKeyInfoTypeChoice()[0].getExtraElement();
- if(verifySequence[i].getCertificateCheck() != null) {
- certificateCheck = new SignatureCheckImpl(
- verifySequence[i].getCertificateCheck().getCode().intValue(),
- verifySequence[i].getCertificateCheck().isInfoSpecified() ?
- verifySequence[i].getCertificateCheck().getInfo().toString() :
- "");
+
+ verifySequence[i].getSignerInfo().getKeyInfoTypeChoice()[0]
+ .getExtraElement();
+ if (verifySequence[i].getCertificateCheck() != null) {
+ certificateCheck = new SignatureCheckImpl(verifySequence[i]
+ .getCertificateCheck().getCode().intValue(),
+ verifySequence[i].getCertificateCheck()
+ .isInfoSpecified() ? verifySequence[i]
+ .getCertificateCheck().getInfo().toString()
+ : "");
} else {
certificateCheck = new SignatureCheckImpl(
1,
"Es konnte keine formal korrekte Zertifikatskette vom Signatorzertifikat zu einem vertrauenswürdigen Wurzelzertifikat konstruiert werden.");
}
-
-
+
SignatureCheck signatureCheck = new SignatureCheckImpl(
- verifySequence[i].getSignatureCheck().getCode().intValue(),
- verifySequence[i].getSignatureCheck().isInfoSpecified() ?
- verifySequence[i].getSignatureCheck().getInfo().toString() :
- "");
-
+ verifySequence[i].getSignatureCheck().getCode()
+ .intValue(),
+ verifySequence[i].getSignatureCheck().isInfoSpecified() ? verifySequence[i]
+ .getSignatureCheck().getInfo().toString()
+ : "");
+
result.setCertificateCheck(certificateCheck);
result.setValueCheckCode(signatureCheck);
result.setVerificationDone(true);
-
- KeyInfoTypeChoice[] keyInfo = verifySequence[i].getSignerInfo().getKeyInfoTypeChoice();
- String xmldisg = keyInfo[0].getExtraElement().toString();
- JAXBElement jaxbElement = (JAXBElement) DsigMarschaller.unmarshalFromString(xmldisg);
+
+ KeyInfoTypeChoice[] keyInfo = verifySequence[i].getSignerInfo()
+ .getKeyInfoTypeChoice();
+ KeyInfoTypeChoice choice = keyInfo[0];
result.setSignatureData(signatureContent);
- if(jaxbElement.getValue() instanceof X509DataType) {
- X509DataType x509Data = (X509DataType)jaxbElement.getValue();
- List<Object> dsigElements = x509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName();
- for(int j = 0; j < dsigElements.size(); j++) {
- Object jaxElement = dsigElements.get(j);
- if(jaxElement instanceof JAXBElement) {
- JAXBElement jaxbElementMember = (JAXBElement)jaxElement;
- if(jaxbElementMember.getName().equals(
- DsigMarschaller.X509DataTypeX509Certificate_QNAME)) {
- if(jaxbElementMember.getValue() instanceof byte[]) {
- byte[] certData = (byte[])jaxbElementMember.getValue();
- X509Certificate certificate = new X509Certificate(certData);
- result.setSignerCertificate(certificate);
- break;
+
+ // extract certificate
+ if (choice.isX509DataSpecified()) {
+ byte[] certData = null;
+ X509DataTypeSequence[] x509Sequence = choice.getX509Data().getX509DataTypeSequence();
+ for(int k = 0; k < x509Sequence.length; k++) {
+ X509DataTypeSequence x509Data = x509Sequence[k];
+ if(x509Data.getX509DataTypeChoice_type0().isX509CertificateSpecified()) {
+ DataHandler handler = x509Data.getX509DataTypeChoice_type0().getX509Certificate();
+ certData = StreamUtils.inputStreamToByteArray(handler.getInputStream());
+ } else if(x509Data.getX509DataTypeChoice_type0().isExtraElementSpecified()) {
+ if(x509Data.getX509DataTypeChoice_type0().getExtraElement().getLocalName().equals(
+ SignatureVerificationServiceStub.QualifiedCertificate.MY_QNAME.getLocalPart())) {
+ result.setQualifiedCertificate(true);
+ }
+ }
+ }
+ X509Certificate certificate = new X509Certificate(
+ certData);
+ result.setSignerCertificate(certificate);
+ } else if (choice.isExtraElementSpecified()) {
+ String xmldisg = choice.getExtraElement().toString();
+ JAXBElement jaxbElement = (JAXBElement) DsigMarschaller
+ .unmarshalFromString(xmldisg);
+ if (jaxbElement.getValue() instanceof X509DataType) {
+ X509DataType x509Data = (X509DataType) jaxbElement
+ .getValue();
+ List<Object> dsigElements = x509Data
+ .getX509IssuerSerialOrX509SKIOrX509SubjectName();
+ for (int j = 0; j < dsigElements.size(); j++) {
+ Object jaxElement = dsigElements.get(j);
+ if (jaxElement instanceof JAXBElement) {
+ JAXBElement jaxbElementMember = (JAXBElement) jaxElement;
+ if (jaxbElementMember
+ .getName()
+ .equals(DsigMarschaller.X509DataTypeX509Certificate_QNAME)) {
+ if (jaxbElementMember.getValue() instanceof byte[]) {
+ byte[] certData = (byte[]) jaxbElementMember
+ .getValue();
+ X509Certificate certificate = new X509Certificate(
+ certData);
+ result.setSignerCertificate(certificate);
+ break;
+ }
}
}
}
@@ -140,7 +186,8 @@ public class PAdESVerifier implements IVerifyFilter {
public List<FilterEntry> getFiters() {
List<FilterEntry> result = new ArrayList<FilterEntry>();
- result.add(new FilterEntry(PDSignature.FILTER_ADOBE_PPKLITE, PDSignature.SUBFILTER_ETSI_CADES_DETACHED));
+ result.add(new FilterEntry(PDSignature.FILTER_ADOBE_PPKLITE,
+ PDSignature.SUBFILTER_ETSI_CADES_DETACHED));
return result;
}
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 34ee1808..ed7ae01c 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
@@ -5,6 +5,8 @@ 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;
@@ -18,10 +20,12 @@ 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 {
@@ -29,6 +33,8 @@ 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)
@@ -59,6 +65,7 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
// 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);
@@ -67,6 +74,10 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
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
@@ -77,6 +88,11 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
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);
}
@@ -90,7 +106,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));
+ //result.add(new FilterEntry(PDSignature.FILTER_ADOBE_PPKLITE, PDSignature.SUBFILTER_ETSI_CADES_DETACHED));
return result;
}