diff options
| author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2014-10-29 14:35:42 +0100 | 
|---|---|---|
| committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2014-10-29 14:35:42 +0100 | 
| commit | 9eba138d47662ce5acdb807ab1102cc44cca0550 (patch) | |
| tree | 9c5e5b4d677ef461be60d631af0ae5db038cf1fb /spss | |
| parent | 35f1f5027aab325f3ccf8e80ef029d26f0d19847 (diff) | |
| parent | 08f30a3dad9cef45d6fea0ce7a6dcb90b6b6ccde (diff) | |
| download | moa-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
Diffstat (limited to 'spss')
| -rw-r--r-- | spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/service/CertificateProviderServlet.java | 178 | ||||
| -rw-r--r-- | spss/server/serverws/src/main/webapp/WEB-INF/web.xml | 14 | 
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> | 
