diff options
| author | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2013-11-28 12:33:02 +0100 | 
|---|---|---|
| committer | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2013-11-28 12:33:02 +0100 | 
| commit | 5225b6852938c91940e0b491286583aa263f61d5 (patch) | |
| tree | 78d236438c222046cedde0351dbb063c0d0740d2 | |
| parent | 7fdb06e32c43e99ec3599639348a3d758b9914a7 (diff) | |
| download | pdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.tar.gz pdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.tar.bz2 pdf-as-4-5225b6852938c91940e0b491286583aa263f61d5.zip | |
Verification with MOA SP working through PAdES Verifier
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;  	} | 
