aboutsummaryrefslogtreecommitdiff
path: root/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java
diff options
context:
space:
mode:
Diffstat (limited to 'spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java')
-rw-r--r--spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java178
1 files changed, 178 insertions, 0 deletions
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..c8a0f68bf
--- /dev/null
+++ b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java
@@ -0,0 +1,178 @@
+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 <code>KeyEntryID</code>s available to the given
+ * <code>keyGroupID</code>.
+ *
+ * @param keyGroupID
+ * The keygroup ID for which the available keys should be
+ * returned.
+ * @return The <code>Set</code> of <code>KeyEntryID</code>s 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) {
+ Logger.error("Unhandled Exception when providing certificate", e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+}