diff options
author | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-11-03 14:38:34 +0100 |
---|---|---|
committer | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-11-03 14:38:34 +0100 |
commit | 0872d2d8a64fd701776b272f49222428d8def07f (patch) | |
tree | 0954a523ad2cc7ad615dbbae5282dd56497e4c6e /moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas | |
parent | e635718b8d6a12e4e80207c8bdf30b02eed3f2ab (diff) | |
download | moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.gz moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.bz2 moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.zip |
initial commit
Diffstat (limited to 'moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas')
3 files changed, 415 insertions, 0 deletions
diff --git a/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/ExtendedVerifyResult.java b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/ExtendedVerifyResult.java new file mode 100644 index 0000000..30bf148 --- /dev/null +++ b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/ExtendedVerifyResult.java @@ -0,0 +1,61 @@ +package at.gv.egovernment.moa.spss.server.pdfas; + +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl; + +public class ExtendedVerifyResult extends VerifyResultImpl implements VerifyResult { + private String qcSource; + private boolean publicAuthority; + private String publicAuthorityID; + private boolean SSCD; + private String sscdSource; + private String issureCountryCode; + + public synchronized String getIssureCountryCode() { + return issureCountryCode; + } + + public synchronized void setIssureCountryCode(String issureCountryCode) { + this.issureCountryCode = issureCountryCode; + } + + public synchronized String getQcSource() { + return qcSource; + } + + public synchronized void setQcSource(String qcSource) { + this.qcSource = qcSource; + } + + public synchronized boolean isPublicAuthority() { + return publicAuthority; + } + + public synchronized void setPublicAuthority(boolean publicAuthority) { + this.publicAuthority = publicAuthority; + } + + public synchronized String getPublicAuthorityID() { + return publicAuthorityID; + } + + public synchronized void setPublicAuthorityID(String publicAuthorityID) { + this.publicAuthorityID = publicAuthorityID; + } + + public synchronized boolean isSSCD() { + return SSCD; + } + + public synchronized void setSSCD(boolean sSCD) { + SSCD = sSCD; + } + + public synchronized String getSscdSource() { + return sscdSource; + } + + public synchronized void setSscdSource(String sscdSource) { + this.sscdSource = sscdSource; + } +} diff --git a/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaConnector.java b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaConnector.java new file mode 100644 index 0000000..6edee0d --- /dev/null +++ b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaConnector.java @@ -0,0 +1,226 @@ +package at.gv.egovernment.moa.spss.server.pdfas; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; +import at.gv.egiz.sl.util.ISignatureConnector; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.cmssign.CMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.impl.CMSContentExplicitImpl; +import at.gv.egovernment.moa.spss.api.impl.CMSDataObjectImpl; +import at.gv.egovernment.moa.spss.api.impl.CreateCMSSignatureRequestImpl; +import at.gv.egovernment.moa.spss.api.impl.DataObjectInfoCMSImpl; +import at.gv.egovernment.moa.spss.api.impl.MetaInfoImpl; +import at.gv.egovernment.moa.spss.api.impl.SingleSignatureInfoCMSImpl; +import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse; +import at.gv.egovernment.moa.spss.server.config.ConfigurationException; +import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry; +import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureCreationInvoker; +import at.gv.egovernment.moa.util.Base64Utils; +import iaik.logging.TransactionId; +import iaik.server.modules.keys.KeyEntryID; +import iaik.server.modules.keys.KeyModule; +import iaik.server.modules.keys.KeyModuleFactory; +import iaik.server.modules.keys.UnknownKeyException; +import iaik.x509.X509Certificate; + +public class InternalMoaConnector implements ISignatureConnector { + + private String keyIdentifier; + private X509Certificate clientCert; + private TransactionId transactionId; + + public InternalMoaConnector(String keyIdentifier, TransactionId transactionId, X509Certificate clientCert) { + this.keyIdentifier = keyIdentifier; + this.transactionId = transactionId; + this.clientCert = clientCert; + } + + private Set buildKeySet(String keyGroupID, KeyModule module) throws ConfigurationException { + ConfigurationProvider config = ConfigurationProvider.getInstance(); + Set keyGroupEntries; + + // get the KeyGroup entries from the configuration + if (clientCert != null) { + Principal issuer = clientCert.getIssuerDN(); + BigInteger serialNumber = clientCert.getSerialNumber(); + + keyGroupEntries = config.getKeyGroupEntries(issuer, serialNumber, keyGroupID); + } else { + keyGroupEntries = config.getKeyGroupEntries(null, null, keyGroupID); + } + + // map the KeyGroup entries to a set of KeyEntryIDs + if (keyGroupEntries == null) { + return Collections.EMPTY_SET; + } else if (keyGroupEntries.size() == 0) { + return Collections.EMPTY_SET; + } else { + + Set keyEntryIDs = module.getPrivateKeyEntryIDs(); + Set keySet = new HashSet(); + Iterator iter; + + // filter out the keys that do not exist in the IAIK configuration + // by walking through the key entries and checking if the exist in + // the + // keyGroupEntries + for (iter = keyEntryIDs.iterator(); iter.hasNext();) { + KeyEntryID entryID = (KeyEntryID) iter.next(); + KeyGroupEntry entry = new KeyGroupEntry(entryID.getModuleID(), entryID.getCertificateIssuer(), + entryID.getCertificateSerialNumber()); + if (keyGroupEntries.contains(entry)) { + keySet.add(entryID); + } + } + return keySet; + } + } + + @Override + public X509Certificate getCertificate(SignParameter parameter) throws PdfAsException { + KeyModule module = KeyModuleFactory.getInstance(this.transactionId); + + Set keySet = null; + try { + keySet = buildKeySet(this.keyIdentifier, module); + } catch (ConfigurationException e2) { + Logger.warn("MOA not correctly configured!", e2); + throw new PdfAsException("MOA not correctly configured!"); + } + + if (keySet == null || keySet.isEmpty()) { + Logger.warn("No keys available for Key Identifier " + this.keyIdentifier + " and given authentication."); + throw new PdfAsException("Invalid Key Identifier: " + this.keyIdentifier); + } + + if (keySet.size() != 1) { + Logger.warn( + "Too many keys available for Key Identifier " + this.keyIdentifier + " and given authentication."); + throw new PdfAsException("Too many keys available for Key Identifier: " + this.keyIdentifier); + } + + Iterator iter; + + // filter out the keys that do not exist in the IAIK configuration + // by walking through the key entries and checking if the exist in + // the + // keyGroupEntries + for (iter = keySet.iterator(); iter.hasNext();) { + KeyEntryID entryID = (KeyEntryID) iter.next(); + + List certChain = null; + try { + certChain = module.getPrivateKeyEntry(entryID).getCertificateChain(); + } catch (UnknownKeyException e1) { + Logger.warn("Unknown KeyIdentifier found!", e1); + throw new PdfAsException("Unknown Key Identifier: " + this.keyIdentifier); + } + + if (certChain != null && !certChain.isEmpty()) { + Logger.trace("Returning Certificate!"); + Certificate keyCert = ((Certificate) certChain.get(0)); + if (keyCert instanceof X509Certificate) { + return (X509Certificate) keyCert; + } else { + try { + return new X509Certificate(keyCert.getEncoded()); + } catch (CertificateEncodingException e) { + Logger.warn("Invalid certificate found!", e); + throw new PdfAsException("Invalid certificate for Key Identifier: " + this.keyIdentifier); + } catch (CertificateException e) { + Logger.warn("Invalid certificate found!", e); + throw new PdfAsException("Invalid certificate for Key Identifier: " + this.keyIdentifier); + } + } + } + + break; + } + + // No Certificate could be found! + Logger.warn("Failed to find keys available for Key Identifier " + this.keyIdentifier + + " and given authentication."); + throw new PdfAsException("Failed to find keys available for Key Identifier: " + this.keyIdentifier); + } + + @Override + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter, RequestedSignature requestedSignature) + throws PdfAsException { + + CreateCMSSignatureRequestImpl createCMSSignatureRequest = new CreateCMSSignatureRequestImpl(); + createCMSSignatureRequest.setKeyIdentifier(this.keyIdentifier); + SingleSignatureInfoCMSImpl singleSignatureInfos = new SingleSignatureInfoCMSImpl(); + + DataObjectInfoCMSImpl dataObjectInfoCMSImpl = new DataObjectInfoCMSImpl(); + + dataObjectInfoCMSImpl.setStructure(DataObjectInfoCMSImpl.STRUCTURE_DETACHED); + + CMSDataObjectImpl cmsDataObjectImpl = new CMSDataObjectImpl(); + + CMSContentExplicitImpl cmsContent = new CMSContentExplicitImpl(); + cmsContent.setBinaryContent(new ByteArrayInputStream(input)); + + cmsDataObjectImpl.setContent(cmsContent); + + MetaInfoImpl metaInfoImpl = new MetaInfoImpl(); + + metaInfoImpl.setMimeType("application/pdf"); + + cmsDataObjectImpl.setMetaInfo(metaInfoImpl); + + dataObjectInfoCMSImpl.setDataObject(cmsDataObjectImpl); + + singleSignatureInfos.setDataObjectInfo(dataObjectInfoCMSImpl); + + createCMSSignatureRequest.getSingleSignatureInfos().add(singleSignatureInfos); + + try { + CreateCMSSignatureResponse createCMSSignatureResponse = CMSSignatureCreationInvoker.getInstance() + .createCMSSignature(createCMSSignatureRequest, Collections.EMPTY_SET); + + if (createCMSSignatureResponse.getResponseElements().isEmpty()) { + Logger.error("MOA CMS Signature response is empty!"); + throw new PdfAsException("MOA CMS Signature response is empty"); + } + + CreateCMSSignatureResponseElement createCMSSignatureResponseElement = (CreateCMSSignatureResponseElement) createCMSSignatureResponse + .getResponseElements().get(0); + + if(createCMSSignatureResponseElement.getResponseType() + == CreateCMSSignatureResponseElement.ERROR_RESPONSE) { + ErrorResponse errorResponse = (ErrorResponse) createCMSSignatureResponseElement; + } else if(createCMSSignatureResponseElement.getResponseType() + == CreateCMSSignatureResponseElement.CMS_SIGNATURE ) { + CMSSignatureResponse cmsSignatureResponse = (CMSSignatureResponse) createCMSSignatureResponseElement; + return Base64Utils.decode(cmsSignatureResponse.getCMSSignature(), true); + } + } catch (MOAException e) { + Logger.error("Failed to create signature!", e); + throw new PdfAsException("Failed to create signature!", e); + } catch (IOException e) { + Logger.error("Failed to create signature!", e); + throw new PdfAsException("Failed to create signature!", e); + } + + return null; + } + +} diff --git a/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaVerifier.java b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaVerifier.java new file mode 100644 index 0000000..f937495 --- /dev/null +++ b/moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaVerifier.java @@ -0,0 +1,128 @@ +package at.gv.egovernment.moa.spss.server.pdfas; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +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.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.verify.SignatureCheck; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.impl.verify.IVerifier; +import at.gv.egiz.pdfas.lib.impl.verify.SignatureCheckImpl; +import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl; +import at.gv.egovernment.moa.spss.MOAException; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse; +import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement; +import at.gv.egovernment.moa.spss.api.common.CheckResult; +import at.gv.egovernment.moa.spss.api.impl.CMSContentExplicitImpl; +import at.gv.egovernment.moa.spss.api.impl.CMSDataObjectImpl; +import at.gv.egovernment.moa.spss.api.impl.MetaInfoImpl; +import at.gv.egovernment.moa.spss.api.impl.VerifyCMSSignatureRequestImpl; +import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker; +import iaik.x509.X509Certificate; + +public class InternalMoaVerifier implements IVerifier { + + public static final String MOA_TRUSTPROFILE = "internal.moa.trustprofile"; + + private String trustProfile; + + private static final Logger logger = LoggerFactory.getLogger(InternalMoaVerifier.class); + + @Override + public List<VerifyResult> verify(byte[] signature, byte[] signatureContent, Date verificationTime) + throws PdfAsException { + + List<VerifyResult> verificationResultList = new ArrayList<VerifyResult>(); + + VerifyCMSSignatureRequestImpl verifyCMSSignatureRequest = new VerifyCMSSignatureRequestImpl(); + verifyCMSSignatureRequest.setDateTime(verificationTime); + verifyCMSSignatureRequest.setTrustProfileId(this.trustProfile); + verifyCMSSignatureRequest.setCMSSignature(new ByteArrayInputStream(signature)); + + CMSContentExplicitImpl cmsContentExplicitImpl = new CMSContentExplicitImpl(); + cmsContentExplicitImpl.setBinaryContent(new ByteArrayInputStream(signatureContent)); + + CMSDataObjectImpl cmsDataObjectImpl = new CMSDataObjectImpl(); + cmsDataObjectImpl.setContent(cmsContentExplicitImpl); + + MetaInfoImpl metaInfo = new MetaInfoImpl(); + metaInfo.setMimeType("application/pdf"); + metaInfo.setDescription("PDF Document"); + cmsDataObjectImpl.setMetaInfo(metaInfo); + + verifyCMSSignatureRequest.setDataObject(cmsDataObjectImpl); + + verifyCMSSignatureRequest.setSignatories(VerifyCMSSignatureRequest.ALL_SIGNATORIES); + + try { + VerifyCMSSignatureResponse verifyCMSSignatureResponse = CMSSignatureVerificationInvoker.getInstance() + .verifyCMSSignature(verifyCMSSignatureRequest); + Iterator iter; + for (iter = verifyCMSSignatureResponse.getResponseElements().iterator(); iter.hasNext();) { + VerifyCMSSignatureResponseElement responseElement = (VerifyCMSSignatureResponseElement) iter.next(); + ExtendedVerifyResult verifyResult = new ExtendedVerifyResult(); + + verifyResult.setCertificateCheck(convertCheck(responseElement.getCertificateCheck())); + verifyResult.setValueCheckCode(convertCheck(responseElement.getSignatureCheck())); + verifyResult.setManifestCheckCode(new SignatureCheckImpl(99, null)); + verifyResult.setQualifiedCertificate(responseElement.getSignerInfo().isQualifiedCertificate()); + verifyResult.setVerificationDone(true); + + if (responseElement.getSignerInfo().getSignerCertificate() instanceof X509Certificate) { + verifyResult.setSignerCertificate( + (X509Certificate) responseElement.getSignerInfo().getSignerCertificate()); + } else { + verifyResult.setSignerCertificate( + new X509Certificate(responseElement.getSignerInfo().getSignerCertificate().getEncoded())); + } + + verifyResult.setQcSource(responseElement.getSignerInfo().getQCSource()); + + verifyResult.setPublicAuthority(responseElement.getSignerInfo().isPublicAuthority()); + verifyResult.setPublicAuthorityID(responseElement.getSignerInfo().getPublicAuhtorityID()); + verifyResult.setSSCD(responseElement.getSignerInfo().isSSCD()); + verifyResult.setSscdSource(responseElement.getSignerInfo().getSSCDSource()); + verifyResult.setIssureCountryCode(responseElement.getSignerInfo().getIssuerCountryCode()); + + verificationResultList.add(verifyResult); + } + } catch (MOAException e) { + logger.error("Failed to verify CMS Signature with MOA", e); + throw new PdfAsException("Failed to verify CMS Signature with MOA", e); + } catch (CertificateEncodingException e) { + logger.error("Failed to verify CMS Signature with MOA", e); + throw new PdfAsException("Failed to verify CMS Signature with MOA", e); + } catch (CertificateException e) { + logger.error("Failed to verify CMS Signature with MOA", e); + throw new PdfAsException("Failed to verify CMS Signature with MOA", e); + } + + return verificationResultList; + } + + private SignatureCheck convertCheck(CheckResult checkResult) { + return new SignatureCheckImpl(checkResult.getCode(), null); + } + + @Override + public void setConfiguration(Configuration config) { + this.trustProfile = config.getValue(MOA_TRUSTPROFILE); + } + + @Override + public SignatureVerificationLevel getLevel() { + return SignatureVerificationLevel.FULL_VERIFICATION; + } + +} |