diff options
Diffstat (limited to 'moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaConnector.java')
-rw-r--r-- | moaSig/moa-sig/src/main/java/at/gv/egovernment/moa/spss/server/pdfas/InternalMoaConnector.java | 226 |
1 files changed, 226 insertions, 0 deletions
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; + } + +} |