aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2014-10-29 14:35:42 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2014-10-29 14:35:42 +0100
commit9eba138d47662ce5acdb807ab1102cc44cca0550 (patch)
tree9c5e5b4d677ef461be60d631af0ae5db038cf1fb
parent35f1f5027aab325f3ccf8e80ef029d26f0d19847 (diff)
parent08f30a3dad9cef45d6fea0ce7a6dcb90b6b6ccde (diff)
downloadmoa-id-spss-9eba138d47662ce5acdb807ab1102cc44cca0550.tar.gz
moa-id-spss-9eba138d47662ce5acdb807ab1102cc44cca0550.tar.bz2
moa-id-spss-9eba138d47662ce5acdb807ab1102cc44cca0550.zip
Merge remote-tracking branch 'remotes/origin/afitzek.moaspss-cert-rest-service' into moa-2.1-Snapshot
-rw-r--r--spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java178
-rw-r--r--spss/server/serverws/src/main/webapp/WEB-INF/web.xml14
2 files changed, 189 insertions, 3 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);
+ }
+ }
+}
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 @@
<servlet>
<servlet-name>ConfigurationServlet</servlet-name>
<display-name>MOA Configuration Servlet</display-name>
- <servlet-class>
- at.gv.egovernment.moa.spss.server.service.ConfigurationServlet
- </servlet-class>
+ <servlet-class>at.gv.egovernment.moa.spss.server.service.ConfigurationServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet>
@@ -22,6 +20,12 @@
org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>CertificateProviderServlet</servlet-name>
+ <display-name>MOA Certificate Provider Servlet</display-name>
+ <servlet-class>at.gv.egovernment.moa.spss.server.service.CertificateProviderServlet</servlet-class>
+ <load-on-startup>0</load-on-startup>
+ </servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
@@ -30,6 +34,10 @@
<servlet-name>ConfigurationServlet</servlet-name>
<url-pattern>/ConfigurationUpdate</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>CertificateProviderServlet</servlet-name>
+ <url-pattern>/Certificate</url-pattern>
+ </servlet-mapping>
<security-constraint>
<web-resource-collection>