From bad8d3cc1051aa22c679801310f94c852821dc4d Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 23 Sep 2014 12:02:50 +0200 Subject: added Certificate Servlet --- .../server/service/CertificateProviderServlet.java | 177 +++++++++++++++++++++ .../serverws/src/main/webapp/WEB-INF/web.xml | 14 +- 2 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java diff --git a/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java new file mode 100644 index 000000000..fe99bcae1 --- /dev/null +++ b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java @@ -0,0 +1,177 @@ +package at.gv.egovernment.moa.spss.server.service; + +import iaik.server.modules.keys.KeyEntryID; +import iaik.server.modules.keys.KeyModule; +import iaik.server.modules.keys.KeyModuleFactory; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.logging.Logger; +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.logging.TransactionId; +import at.gv.egovernment.moa.spss.server.transaction.TransactionIDGenerator; + +/** + * + * @author Andreas Fitzek + * @version $Id$ + */ +public class CertificateProviderServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = -6907582473072190122L; + + /** The property name for accessing the X509 client certificate chain. */ + private static final String X509_CERTIFICATE_PROPERTY = "javax.servlet.request.X509Certificate"; + + public static final String PARAM_KEYID = "id"; + + /** + * Build the set of KeyEntryIDs available to the given + * keyGroupID. + * + * @param keyGroupID + * The keygroup ID for which the available keys should be + * returned. + * @return The Set of KeyEntryIDs identifying the + * available keys. + * @throws ConfigurationException + */ + private Set buildKeySet(String keyGroupID, X509Certificate cert, KeyModule module) + throws ConfigurationException { + ConfigurationProvider config = ConfigurationProvider.getInstance(); + Set keyGroupEntries; + + // get the KeyGroup entries from the configuration + if (cert != null) { + Principal issuer = cert.getIssuerDN(); + BigInteger serialNumber = cert.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 null; + } 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; + } + } + + private X509Certificate getClientCertificate(HttpServletRequest request) { + X509Certificate[] clientCert = (X509Certificate[]) request + .getAttribute(X509_CERTIFICATE_PROPERTY); + if(clientCert != null) { + return clientCert[0]; + } + return null; + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + try { + X509Certificate cert = getClientCertificate(request); + String keyId = request.getParameter(PARAM_KEYID); + + if(keyId == null) { + Logger.warn(PARAM_KEYID + " not provided in Request. Returning: " + HttpServletResponse.SC_BAD_REQUEST); + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + String transactionId = TransactionIDGenerator.nextID(); + + KeyModule module = KeyModuleFactory.getInstance(new TransactionId( + transactionId)); + + Set keySet = buildKeySet(keyId, cert, module); + + if(keySet == null || keySet.isEmpty()) { + Logger.warn("No keys available for Key Identifier " + keyId + " and given authentication."); + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + + + if(keySet.size() != 1) { + Logger.warn("Too many keys available for Key Identifier " + keyId + " and given authentication."); + response.sendError(HttpServletResponse.SC_CONFLICT); + return; + } + + 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 = module.getPrivateKeyEntry(entryID).getCertificateChain(); + + if(certChain != null && !certChain.isEmpty()) { + Logger.trace("Returning Certificate!"); + Certificate keyCert = ((Certificate)certChain.get(0)); + byte[] certData = keyCert.getEncoded(); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/pkix-cert"); + response.setHeader("Content-disposition","attachment; filename=\"" + keyId + ".cer\""); + response.getOutputStream().write(certData); + response.getOutputStream().close(); + return; + } + + break; + } + + // No Certificate could be found! + Logger.warn("Failed to find keys available for Key Identifier " + keyId + " and given authentication."); + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } catch(Throwable e) { + + } + } +} diff --git a/spss/server/serverws/src/main/webapp/WEB-INF/web.xml b/spss/server/serverws/src/main/webapp/WEB-INF/web.xml index b68ee850e..5de9f1d9c 100644 --- a/spss/server/serverws/src/main/webapp/WEB-INF/web.xml +++ b/spss/server/serverws/src/main/webapp/WEB-INF/web.xml @@ -10,9 +10,7 @@ ConfigurationServlet MOA Configuration Servlet - - at.gv.egovernment.moa.spss.server.service.ConfigurationServlet - + at.gv.egovernment.moa.spss.server.service.ConfigurationServlet 0 @@ -22,6 +20,12 @@ org.apache.axis.transport.http.AxisServlet + + CertificateProviderServlet + MOA Certificate Provider Servlet + at.gv.egovernment.moa.spss.server.service.CertificateProviderServlet + 0 + AxisServlet /services/* @@ -30,6 +34,10 @@ ConfigurationServlet /ConfigurationUpdate + + CertificateProviderServlet + /Certificate + -- cgit v1.2.3 From 08f30a3dad9cef45d6fea0ce7a6dcb90b6b6ccde Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 23 Sep 2014 12:16:02 +0200 Subject: filled error handler in certificate servlet --- .../moa/spss/server/service/CertificateProviderServlet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java index fe99bcae1..c8a0f68bf 100644 --- a/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java +++ b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java @@ -171,7 +171,8 @@ public class CertificateProviderServlet extends HttpServlet { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } catch(Throwable e) { - + Logger.error("Unhandled Exception when providing certificate", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } } -- cgit v1.2.3