aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-07-10 12:58:25 +0200
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-07-10 12:58:25 +0200
commit0bfafff409078ef49b2d4a0d71405e8f5b0eb078 (patch)
tree6b0eb440acbca7407ec77a23fca1ad653c2d9a81
parentaf90012c848711a4c9010dbcf71694dbfbca0e86 (diff)
downloadpdf-as-4-0bfafff409078ef49b2d4a0d71405e8f5b0eb078.tar.gz
pdf-as-4-0bfafff409078ef49b2d4a0d71405e8f5b0eb078.tar.bz2
pdf-as-4-0bfafff409078ef49b2d4a0d71405e8f5b0eb078.zip
Implemented Verification level (Full incl. Certificate Path, and Integrity Only)
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java31
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java33
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java5
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/VerifyParameterImpl.java12
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FullVerifier.java211
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifier.java15
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IntegrityVerifier.java95
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java41
-rw-r--r--signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java194
-rw-r--r--signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java75
11 files changed, 454 insertions, 262 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 eee47888..e36883ab 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
@@ -49,6 +49,7 @@ 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;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
import at.gv.egiz.pdfas.sigs.pades.PAdESSigner;
import at.gv.egiz.pdfas.sigs.pades.PAdESSignerKeystore;
import at.gv.egiz.sl.util.BKUSLConnector;
@@ -82,6 +83,11 @@ public class Main {
public static final String CLI_ARG_VERIFY_WHICH_SHORT = "vw";
public static final String CLI_ARG_VERIFY_WHICH = "verify_which";
+
+ public static final String CLI_ARG_VERIFY_LEVEL_SHORT = "vl";
+ public static final String CLI_ARG_VERIFY_LEVEL = "verify_level";
+ public static final String CLI_ARG_VERIFY_LEVEL_OPTION_FULL = "full";
+ public static final String CLI_ARG_VERIFY_LEVEL_OPTION_INT_ONLY = "intOnly";
public static final String CLI_ARG_KEYSTORE_FILE_SHORT = "ksf";
public static final String CLI_ARG_KEYSTORE_FILE = "ks_file";
@@ -169,6 +175,13 @@ public class Main {
true,
"[optional] zero based number of the signature to be verified. If omitted, all signatures are verified.");
cliOptions.addOption(verifywhichOption);
+
+ Option verifyLevelOption = new Option(
+ CLI_ARG_VERIFY_LEVEL_SHORT,
+ CLI_ARG_VERIFY_LEVEL,
+ true,
+ "[optional] Verification Level Full certificate verification, or only integrity Verification (" + CLI_ARG_VERIFY_LEVEL_OPTION_FULL + " | " + CLI_ARG_VERIFY_LEVEL_OPTION_INT_ONLY + ")");
+ cliOptions.addOption(verifyLevelOption);
Option outputOption = new Option(CLI_ARG_OUTPUT_SHORT, CLI_ARG_OUTPUT,
true, "The output file");
@@ -423,6 +436,22 @@ public class Main {
String whichValue = cli.getOptionValue(CLI_ARG_VERIFY_WHICH_SHORT);
which = Integer.parseInt(whichValue);
}
+
+ SignatureVerificationLevel lvl = SignatureVerificationLevel.FULL_VERIFICATION;
+
+ if (cli.hasOption(CLI_ARG_VERIFY_LEVEL_SHORT)) {
+ String levelValue = cli.getOptionValue(CLI_ARG_VERIFY_LEVEL_SHORT);
+ if(levelValue.equals(CLI_ARG_VERIFY_LEVEL_OPTION_FULL)) {
+ lvl = SignatureVerificationLevel.FULL_VERIFICATION;
+ } else if(levelValue.equals(CLI_ARG_VERIFY_LEVEL_OPTION_INT_ONLY)) {
+ lvl = SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION;
+ } else {
+ System.out.println("Invalid value for verification Level: " + levelValue);
+ System.out.println("Allowed values are: " + CLI_ARG_VERIFY_LEVEL_OPTION_FULL
+ + ", " + CLI_ARG_VERIFY_LEVEL_OPTION_INT_ONLY);
+ throw new Exception("Invalid value for verification Level: " + levelValue);
+ }
+ }
String confOutputFile = null;
@@ -452,7 +481,7 @@ public class Main {
VerifyParameter verifyParameter = PdfAsFactory.createVerifyParameter(
configuration, dataSource);
-
+ verifyParameter.setSignatureVerificationLevel(lvl);
verifyParameter.setDataSource(dataSource);
verifyParameter.setConfiguration(configuration);
verifyParameter.setWhichSignature(which);
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java
index 3523c268..223e3e61 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java
@@ -30,6 +30,25 @@ import at.gv.egiz.pdfas.lib.api.PdfAsParameter;
public interface VerifyParameter extends PdfAsParameter {
/**
+ * The signature Verification Level defines what should be verified
+ */
+ public enum SignatureVerificationLevel {
+ /**
+ * Only verifies the the Signatures integrity
+ *
+ * This option does not perform a verification of the signing Certificate
+ * and does not requires MOA-SP
+ */
+ INTEGRITY_ONLY_VERIFICATION,
+ /**
+ * Uses MOA-SP to verify the Signature and verifies the Certification Path
+ *
+ * This is the default value
+ */
+ FULL_VERIFICATION
+ }
+
+ /**
* Gets which signature should be verified
*
* This is a 0 based index of the signatures
@@ -58,4 +77,18 @@ public interface VerifyParameter extends PdfAsParameter {
* @param verificationTime
*/
public void setVerificationTime(Date verificationTime);
+
+ /**
+ * Sets the verification Level
+ *
+ * @param signatureVerificationLevel
+ */
+ public void setSignatureVerificationLevel(SignatureVerificationLevel signatureVerificationLevel);
+
+ /**
+ * Gets the verification level
+ *
+ * @return
+ */
+ public SignatureVerificationLevel getSignatureVerificationLevel();
}
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 7dcdca2b..40e7faf5 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
@@ -81,6 +81,7 @@ import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+import at.gv.egiz.pdfas.lib.impl.verify.IVerifier;
import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter;
import at.gv.egiz.pdfas.lib.impl.verify.VerifierDispatcher;
import at.gv.egiz.pdfas.lib.util.SignatureUtils;
@@ -281,11 +282,13 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
dict.getNameAsString("Filter"),
dict.getNameAsString("SubFilter"));
+ IVerifier lvlVerifier = verifier.getVerifierByLevel(parameter.getSignatureVerificationLevel());
+ lvlVerifier.setConfiguration(parameter.getConfiguration());
if (verifyFilter != null) {
List<VerifyResult> results = verifyFilter.verify(
contentData.toByteArray(),
content.getBytes(),
- parameter.getVerificationTime(), bytes);
+ parameter.getVerificationTime(), bytes, lvlVerifier);
if (results != null && !results.isEmpty()) {
result.addAll(results);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/VerifyParameterImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/VerifyParameterImpl.java
index b7b81761..166c17e0 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/VerifyParameterImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/VerifyParameterImpl.java
@@ -35,6 +35,9 @@ public class VerifyParameterImpl extends PdfAsParameterImpl implements VerifyPar
protected Date verificationTime = null;
+ protected SignatureVerificationLevel signatureVerificationLevel =
+ SignatureVerificationLevel.FULL_VERIFICATION;
+
public VerifyParameterImpl(Configuration configuration,
DataSource dataSource) {
super(configuration, dataSource);
@@ -55,4 +58,13 @@ public class VerifyParameterImpl extends PdfAsParameterImpl implements VerifyPar
public void setVerificationTime(Date verificationTime) {
this.verificationTime = verificationTime;
}
+
+ public void setSignatureVerificationLevel(
+ SignatureVerificationLevel signatureVerificationLevel) {
+ this.signatureVerificationLevel = signatureVerificationLevel;
+ }
+
+ public SignatureVerificationLevel getSignatureVerificationLevel() {
+ return this.signatureVerificationLevel;
+ }
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FullVerifier.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FullVerifier.java
new file mode 100644
index 00000000..7b40707c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FullVerifier.java
@@ -0,0 +1,211 @@
+package at.gv.egiz.pdfas.lib.impl.verify;
+
+import iaik.x509.X509Certificate;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import javax.activation.DataHandler;
+import javax.xml.bind.JAXBElement;
+
+import org.apache.axis2.databinding.types.Token;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.dsig.X509DataType;
+import at.gv.egiz.dsig.util.DsigMarschaller;
+import at.gv.egiz.moa.ByteArrayDataSource;
+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.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.messages.CodesResolver;
+import at.gv.egiz.pdfas.common.utils.StreamUtils;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
+
+public class FullVerifier implements IVerifier {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(FullVerifier.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 List<VerifyResult> verify(byte[] signature, byte[] signatureContent,
+ Date verificationTime) 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();
+ Token token = new Token();
+ token.setValue(this.moaTrustProfile);
+ verifyCMSSignatureRequest.setTrustProfileID(token);
+
+ CMSDataObjectOptionalMetaType cmsDataObjectOptionalMetaType = new CMSDataObjectOptionalMetaType();
+ CMSContentBaseType cmsDataContent = new CMSContentBaseType();
+ cmsDataContent.setBase64Content(new DataHandler(
+ new ByteArrayDataSource(signatureContent, "application/pdf")));
+ DataHandler cmsSignature = new DataHandler(new ByteArrayDataSource(
+ signature, "application/pdf"));
+ cmsDataObjectOptionalMetaType.setContent(cmsDataContent);
+ verifyCMSSignatureRequest.setCMSSignature(cmsSignature);
+ verifyCMSSignatureRequest
+ .setDataObject(cmsDataObjectOptionalMetaType);
+ if (verificationTime != null) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(verificationTime);
+ verifyCMSSignatureRequest.setDateTime(cal);
+ }
+ // cmsDataObjectOptionalMetaType.
+ VerifyCMSSignatureResponse response = service
+ .verifyCMSSignature(verifyCMSSignatureRequest);
+
+ logger.debug("Got Verify Response from MOA");
+
+ VerifyCMSSignatureResponseTypeSequence[] verifySequence = response
+ .getVerifyCMSSignatureResponse()
+ .getVerifyCMSSignatureResponseTypeSequence();
+ for (int i = 0; i < verifySequence.length; i++) {
+ VerifyResultImpl result = new VerifyResultImpl();
+ logger.debug(" ---------------------- ");
+ logger.debug("Signature: " + i);
+
+ SignatureCheckImpl 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()
+ : "");
+ } else {
+ certificateCheck = new SignatureCheckImpl(
+ 1,
+ "");
+ }
+
+ if(certificateCheck.getMessage() == null || certificateCheck.getMessage().trim().length() == 0) {
+ String resourceString = "verify.cert." + certificateCheck.getCode();
+ String message = CodesResolver.resolveMessage(resourceString);
+ certificateCheck.setMessage(message);
+ }
+
+ logger.debug("Certificate Check: " + certificateCheck.getCode() + " [" + certificateCheck.getMessage() + "]");
+
+ SignatureCheckImpl signatureCheck = new SignatureCheckImpl(
+ verifySequence[i].getSignatureCheck().getCode()
+ .intValue(),
+ verifySequence[i].getSignatureCheck().isInfoSpecified() ? verifySequence[i]
+ .getSignatureCheck().getInfo().toString()
+ : "");
+
+ if(signatureCheck.getMessage() == null || signatureCheck.getMessage().trim().length() == 0) {
+ String resourceString = "verify.value." + signatureCheck.getCode();
+ String message = CodesResolver.resolveMessage(resourceString);
+ signatureCheck.setMessage(message);
+ }
+
+ logger.debug("Signature Check: " + signatureCheck.getCode() + " [" + signatureCheck.getMessage() + "]");
+
+ result.setCertificateCheck(certificateCheck);
+ result.setValueCheckCode(signatureCheck);
+ result.setVerificationDone(true);
+
+ KeyInfoTypeChoice[] keyInfo = verifySequence[i].getSignerInfo()
+ .getKeyInfoTypeChoice();
+ KeyInfoTypeChoice choice = keyInfo[0];
+
+ // 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;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ resultList.add(result);
+
+ logger.debug(" ---------------------- ");
+ }
+ } catch (Throwable e) {
+ logger.error("Verification failed", e);
+ throw new PdfAsException("error.pdf.verify.02", e);
+ }
+ return resultList;
+ }
+
+ public void setConfiguration(Configuration config) {
+ this.moaEndpoint = config.getValue(MOA_VERIFY_URL);
+ this.moaTrustProfile = config.getValue(MOA_VERIFY_TRUSTPROFILE);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifier.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifier.java
new file mode 100644
index 00000000..7badb9be
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifier.java
@@ -0,0 +1,15 @@
+package at.gv.egiz.pdfas.lib.impl.verify;
+
+import java.util.Date;
+import java.util.List;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
+
+public interface IVerifier {
+ public List<VerifyResult> verify(byte[] signature,
+ byte[] signatureContent, Date verificationTime) throws PdfAsException;
+
+ public void setConfiguration(Configuration config);
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
index 6f6a58b0..1bc56162 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
@@ -32,6 +32,8 @@ import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
public interface IVerifyFilter {
public void setConfiguration(Configuration config);
- public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent, Date verificationTime, int[] byteRange) throws PdfAsException;
+ public List<VerifyResult> verify(byte[] contentData,
+ byte[] signatureContent, Date verificationTime,
+ int[] byteRange, IVerifier verifier) throws PdfAsException;
public List<FilterEntry> getFiters();
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IntegrityVerifier.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IntegrityVerifier.java
new file mode 100644
index 00000000..01604a6b
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IntegrityVerifier.java
@@ -0,0 +1,95 @@
+package at.gv.egiz.pdfas.lib.impl.verify;
+
+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.security.SignatureException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+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;
+
+public class IntegrityVerifier implements IVerifier {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(FullVerifier.class);
+
+ public List<VerifyResult> verify(byte[] signature, byte[] signatureContent,
+ Date verificationTime) throws PdfAsException {
+ try {
+ List<VerifyResult> result = new ArrayList<VerifyResult>();
+
+ SignedData signedData = new SignedData(signatureContent, new AlgorithmID[] {
+ AlgorithmID.sha256, AlgorithmID.sha1, AlgorithmID.ripeMd160, AlgorithmID.ripeMd160_ISO
+ });
+ ContentInfo ci = new ContentInfo(new ByteArrayInputStream(signature
+ ));
+ if (!ci.getContentType().equals(ObjectID.cms_signedData)) {
+ throw new PdfAsException("error.pdf.verify.01");
+ }
+ //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);
+ logger.info("Signature Algo: {}, Digest {}",
+ signedData.getSignerInfos()[i].getSignatureAlgorithm(),
+ signedData.getSignerInfos()[i].getDigestAlgorithm());
+ // 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("error.pdf.verify.02", e);
+ }
+ }
+
+ public void setConfiguration(Configuration config) {
+
+ }
+}
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 0c37e637..6851865b 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
@@ -35,6 +35,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;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
public class VerifierDispatcher {
@@ -60,7 +61,7 @@ public class VerifierDispatcher {
} else {
classes = defaultClasses;
}
-
+
List<String> filteredClasses = new ArrayList<String>();
for (int i = 0; i < classes.length; i++) {
@@ -72,17 +73,17 @@ public class VerifierDispatcher {
logger.error("Cannot find Verifier class: " + clsName, e);
}
}
-
+
String[] clsNames = new String[filteredClasses.size()];
for (int i = 0; i < filteredClasses.size(); i++) {
clsNames[i] = filteredClasses.get(i);
}
-
+
dumpVerifierClasses(clsNames);
-
+
return clsNames;
}
-
+
private void dumpVerifierClasses(String[] clsNames) {
for (int i = 0; i < clsNames.length; i++) {
String clsName = clsNames[i];
@@ -93,21 +94,18 @@ public class VerifierDispatcher {
public VerifierDispatcher(ISettings settings) {
// TODO: add configuration parameter to set verifier
- //Map<String, String> verifierClasses = settings
- // .getValuesPrefix(CONF_VERIFIER);
+ // Map<String, String> verifierClasses = settings
+ // .getValuesPrefix(CONF_VERIFIER);
String[] currentClasses = null;
- //if (verifierClasses == null || verifierClasses.isEmpty()) {
+ // if (verifierClasses == null || verifierClasses.isEmpty()) {
logger.info("Getting Verifier classes");
currentClasses = getClasses(settings);
- /*} else {
- currentClasses = new String[verifierClasses.values().size()];
- Iterator<String> classIt = verifierClasses.values().iterator();
- int j = 0;
- while (classIt.hasNext()) {
- currentClasses[j] = classIt.next();
- j++;
- }
- }*/
+ /*
+ * } else { currentClasses = new
+ * String[verifierClasses.values().size()]; Iterator<String> classIt =
+ * verifierClasses.values().iterator(); int j = 0; while
+ * (classIt.hasNext()) { currentClasses[j] = classIt.next(); j++; } }
+ */
try {
for (int i = 0; i < currentClasses.length; i++) {
String clsName = currentClasses[i];
@@ -155,4 +153,13 @@ public class VerifierDispatcher {
return filters.get(subfilter);
}
+
+ public IVerifier getVerifierByLevel(SignatureVerificationLevel level) {
+ switch (level) {
+ case INTEGRITY_ONLY_VERIFICATION:
+ return new IntegrityVerifier();
+ default:
+ return new FullVerifier();
+ }
+ }
}
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 2df2368e..d1e185ab 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
@@ -23,41 +23,21 @@
******************************************************************************/
package at.gv.egiz.pdfas.sigs.pades;
-import iaik.x509.X509Certificate;
-
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.Date;
import java.util.List;
-import javax.activation.DataHandler;
-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;
-import at.gv.egiz.moa.ByteArrayDataSource;
-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.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.messages.CodesResolver;
import at.gv.egiz.pdfas.common.utils.PDFUtils;
-import at.gv.egiz.pdfas.common.utils.StreamUtils;
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.IVerifier;
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 PAdESVerifier implements IVerifyFilter {
@@ -76,169 +56,19 @@ public class PAdESVerifier implements IVerifyFilter {
@SuppressWarnings("rawtypes")
public List<VerifyResult> verify(byte[] contentData,
- byte[] signatureContent, Date verificationTime, int[] byteRange)
+ byte[] signatureContent, Date verificationTime, int[] byteRange, IVerifier verifier)
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();
- Token token = new Token();
- token.setValue(this.moaTrustProfile);
- verifyCMSSignatureRequest.setTrustProfileID(token);
-
- byte[] data = contentData;
- byte[] signature = signatureContent;
-
- CMSDataObjectOptionalMetaType cmsDataObjectOptionalMetaType = new CMSDataObjectOptionalMetaType();
- CMSContentBaseType cmsDataContent = new CMSContentBaseType();
- cmsDataContent.setBase64Content(new DataHandler(
- new ByteArrayDataSource(data, "application/pdf")));
- DataHandler cmsSignature = new DataHandler(new ByteArrayDataSource(
- signature, "application/pdf"));
- cmsDataObjectOptionalMetaType.setContent(cmsDataContent);
- verifyCMSSignatureRequest.setCMSSignature(cmsSignature);
- verifyCMSSignatureRequest
- .setDataObject(cmsDataObjectOptionalMetaType);
- if (verificationTime != null) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(verificationTime);
- verifyCMSSignatureRequest.setDateTime(cal);
- }
- // cmsDataObjectOptionalMetaType.
- VerifyCMSSignatureResponse response = service
- .verifyCMSSignature(verifyCMSSignatureRequest);
-
- logger.debug("Got Verify Response from MOA");
-
- VerifyCMSSignatureResponseTypeSequence[] verifySequence = response
- .getVerifyCMSSignatureResponse()
- .getVerifyCMSSignatureResponseTypeSequence();
- for (int i = 0; i < verifySequence.length; i++) {
- VerifyResultImpl result = new VerifyResultImpl();
- logger.debug(" ---------------------- ");
- logger.debug("Signature: " + i);
-
- SignatureCheckImpl 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()
- : "");
- } else {
- certificateCheck = new SignatureCheckImpl(
- 1,
- "");
- }
-
- if(certificateCheck.getMessage() == null || certificateCheck.getMessage().trim().length() == 0) {
- String resourceString = "verify.cert." + certificateCheck.getCode();
- String message = CodesResolver.resolveMessage(resourceString);
- certificateCheck.setMessage(message);
- }
-
- logger.debug("Certificate Check: " + certificateCheck.getCode() + " [" + certificateCheck.getMessage() + "]");
-
- SignatureCheckImpl signatureCheck = new SignatureCheckImpl(
- verifySequence[i].getSignatureCheck().getCode()
- .intValue(),
- verifySequence[i].getSignatureCheck().isInfoSpecified() ? verifySequence[i]
- .getSignatureCheck().getInfo().toString()
- : "");
-
- if(signatureCheck.getMessage() == null || signatureCheck.getMessage().trim().length() == 0) {
- String resourceString = "verify.value." + signatureCheck.getCode();
- String message = CodesResolver.resolveMessage(resourceString);
- signatureCheck.setMessage(message);
- }
-
- logger.debug("Signature Check: " + signatureCheck.getCode() + " [" + signatureCheck.getMessage() + "]");
-
- result.setCertificateCheck(certificateCheck);
- result.setValueCheckCode(signatureCheck);
- result.setVerificationDone(true);
-
- KeyInfoTypeChoice[] keyInfo = verifySequence[i].getSignerInfo()
- .getKeyInfoTypeChoice();
- KeyInfoTypeChoice choice = keyInfo[0];
- result.setSignatureData(PDFUtils.blackOutSignature(data, byteRange));
-
- // 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;
- }
- }
- }
- }
- }
- }
-
- resultList.add(result);
-
- logger.debug(" ---------------------- ");
- }
- } catch (Throwable e) {
- logger.error("Verification failed", e);
- throw new PdfAsException("error.pdf.verify.02", e);
+
+ byte[] data = contentData;
+ byte[] signature = signatureContent;
+
+ List<VerifyResult> verifieResults = verifier.verify(signature, data, verificationTime);
+ for(int i =0; i < verifieResults.size();i++) {
+ VerifyResultImpl result = (VerifyResultImpl)verifieResults.get(i);
+ result.setSignatureData(PDFUtils.blackOutSignature(data, byteRange));
}
- return resultList;
+
+ return verifieResults;
}
public List<FilterEntry> getFiters() {
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
index bef034b1..fb7fa5ab 100644
--- 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
@@ -46,6 +46,7 @@ import at.gv.egiz.pdfas.common.utils.PDFUtils;
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.IVerifier;
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;
@@ -57,68 +58,22 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
public PKCS7DetachedVerifier() {
}
- public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent, Date verificationTime, int[] byteRange)
+ public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent,
+ Date verificationTime, int[] byteRange, IVerifier verifier)
throws PdfAsException {
- try {
- List<VerifyResult> result = new ArrayList<VerifyResult>();
-
- SignedData signedData = new SignedData(contentData, new AlgorithmID[] {
- AlgorithmID.sha256, AlgorithmID.sha1, AlgorithmID.ripeMd160, AlgorithmID.ripeMd160_ISO
- });
- ContentInfo ci = new ContentInfo(new ByteArrayInputStream(
- signatureContent));
- if (!ci.getContentType().equals(ObjectID.cms_signedData)) {
- throw new PdfAsException("error.pdf.verify.01");
- }
- //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(PDFUtils.blackOutSignature(contentData, byteRange));
- try {
- // verify the signature for SignerInfo at index i
- X509Certificate signer_cert = signedData.verify(i);
- logger.info("Signature Algo: {}, Digest {}",
- signedData.getSignerInfos()[i].getSignatureAlgorithm(),
- signedData.getSignerInfos()[i].getDigestAlgorithm());
- // 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("error.pdf.verify.02", e);
+
+ byte[] data = contentData;
+ byte[] signature = signatureContent;
+
+ List<VerifyResult> verifieResults = verifier.verify(signature, data, verificationTime);
+ for(int i =0; i < verifieResults.size();i++) {
+ VerifyResultImpl result = (VerifyResultImpl)verifieResults.get(i);
+ result.setSignatureData(PDFUtils.blackOutSignature(data, byteRange));
}
+
+ return verifieResults;
+
+
}
public List<FilterEntry> getFiters() {