diff options
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; } |