package at.gv.egovernment.moa.id.auth.servlet;
import iaik.pki.PKIException;
import iaik.x509.X509Certificate;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateEncodingException;
import java.util.Map;
import javax.net.ssl.SSLSocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.axis.encoding.Base64;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.lang.StringEscapeUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import at.gv.egovernment.moa.id.AuthenticationException;
import at.gv.egovernment.moa.id.MOAIDException;
import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
import at.gv.egovernment.moa.id.auth.WrongParametersException;
import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWConstants;
import at.gv.egovernment.moa.id.config.ConnectionParameter;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.id.util.SSLUtils;
import at.gv.egovernment.moa.id.util.ServletUtils;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSessionId;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClient;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClientException;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.DOMUtils;
/**
* Servlet requested for getting the foreign eID
* provided by the security layer implementation.
* Utilizes the {@link AuthenticationServer}.
*
*/
public class VerifyCertificateServlet extends AuthServlet {
/**
* Constructor for VerifyCertificateServlet.
*/
public VerifyCertificateServlet() {
super();
}
/**
* GET requested by security layer implementation to verify
* that data URL resource is available.
* @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Logger.debug("GET VerifyCertificateServlet");
resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
}
/**
* Gets the signer certificate from the InfoboxReadRequest and
* responds with a new
* CreateXMLSignatureRequest
.
*
* Request parameters:
*
* - MOASessionID: ID of associated authentication session
* - XMLResponse:
<InfoboxReadResponse>
*
* @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Logger.debug("POST VerifyCertificateServlet");
resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
Map parameters;
try
{
parameters = getParameters(req);
} catch (FileUploadException e)
{
Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage());
throw new IOException(e.getMessage());
}
String sessionID = req.getParameter(PARAM_SESSIONID);
// escape parameter strings
sessionID = StringEscapeUtils.escapeHtml(sessionID);
AuthenticationSession session = null;
try {
// check parameter
if (!ParamValidatorUtils.isValidSessionID(sessionID))
throw new WrongParametersException("VerifyCertificate", PARAM_SESSIONID, "auth.12");
session = AuthenticationServer.getSession(sessionID);
X509Certificate cert = AuthenticationServer.getInstance().getCertificate(sessionID, parameters);
if (cert == null) {
Logger.error("Certificate could not be read.");
throw new AuthenticationException("auth.14", null);
}
boolean useMandate = session.getUseMandate();
if (useMandate) {
// Mandate Modus
// make request to MIS
AuthConfigurationProvider authConf= AuthConfigurationProvider.getInstance();
ConnectionParameter connectionParameters = authConf.getOnlineMandatesConnectionParameter();
SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters);
// get identitity link as byte[]
Element elem = session.getIdentityLink().getSamlAssertion();
String s = DOMUtils.serializeNode(elem);
// byte[] idl = DOMUtils.nodeToByteArray(elem);
// String s = new String(idl);
byte[] idl = s.getBytes();
// redirect url
// build redirect(to the GetMISSessionIdSerlvet)
String redirectURL =
new DataURLBuilder().buildDataURL(
session.getAuthURL(),
GET_MIS_SESSIONID,
session.getSessionID());
String oaURL = session.getOAURLRequested();
OAAuthParameter oaParam = authConf.getOnlineApplicationParameter(oaURL);
String profiles = oaParam.getMandateProfiles();
if (profiles == null) {
Logger.error("No Mandate/Profile for OA configured.");
throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID});
}
String profilesArray[] = profiles.split(",");
for(int i = 0; i < profilesArray.length; i++) {
profilesArray[i] = profilesArray[i].trim();
}
MISSessionId misSessionID = MISSimpleClient.sendSessionIdRequest(connectionParameters.getUrl(), idl, cert.getEncoded(), redirectURL, profilesArray, sslFactory);
String redirectMISGUI = misSessionID.getRedirectURL();
if (misSessionID == null) {
Logger.error("Fehler bei Anfrage an Vollmachten Service. MIS Session ID ist null.");
throw new MISSimpleClientException("Fehler bei Anfrage an Vollmachten Service.");
}
session.setMISSessionID(misSessionID.getSessiondId());
resp.setStatus(302);
resp.addHeader("Location", redirectMISGUI);
Logger.debug("REDIRECT TO: " + redirectURL);
}
else {
// Foreign Identities Modus
String createXMLSignatureRequest = AuthenticationServer.getInstance().createXMLSignatureRequestForeignID(sessionID, cert);
// build dataurl (to the GetForeignIDSerlvet)
String dataurl =
new DataURLBuilder().buildDataURL(
session.getAuthURL(),
REQ_GET_FOREIGN_ID,
session.getSessionID());
ServletUtils.writeCreateXMLSignatureRequest(resp, session, createXMLSignatureRequest, AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, "GetForeignID", dataurl);
Logger.debug("Send CreateXMLSignatureRequest to BKU");
}
}
catch (MOAIDException ex) {
handleError(null, ex, req, resp);
} catch (GeneralSecurityException ex) {
handleError(null, ex, req, resp);
} catch (PKIException e) {
handleError(null, e, req, resp);
} catch (MISSimpleClientException e) {
handleError(null, e, req, resp);
} catch (TransformerException e) {
handleError(null, e, req, resp);
}
}
/**
* Adds a parameter to a URL.
* @param url the URL
* @param paramname parameter name
* @param paramvalue parameter value
* @return the URL with parameter added
*/
private static String addURLParameter(String url, String paramname, String paramvalue) {
String param = paramname + "=" + paramvalue;
if (url.indexOf("?") < 0)
return url + "?" + param;
else
return url + "&" + param;
}
/**
* Does the request to the SZR-GW
* @param givenname
* @param familyname
* @param dateofbirth
* @return Identity link assertion
* @throws SZRGWClientException
*/
/*private Element getIdentityLink(Element signature) throws SZRGWClientException {*/
// private Element getIdentityLink(X509Certificate cert) throws SZRGWClientException {
//
// SZRGWClient client = new SZRGWClient();
//
// try {
// AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
// ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
// //url = "http://localhost:8081/szr-gateway/services/IdentityLinkCreation";
// Logger.debug("Connection Parameters: " + connectionParameters);
// client.setAddress(connectionParameters.getUrl());
// if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) {
// Logger.debug("Initialisiere SSL Verbindung");
// try {
// client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters));
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (GeneralSecurityException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (PKIException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
//
// Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
//
//
// }
// catch (ConfigurationException e) {
// Logger.warn(e);
// Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
//
// }
// // create request
// Document doc = buildGetIdentityLinkRequest(cert);
// Element request = doc.getDocumentElement();
// CreateIdentityLinkResponse response = null;
//
// //try {
// response = client.createIdentityLinkResponse(request);
// //} catch (SZRGWClientException e) {
// // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt.
// // client = new SZRGWClient(url);
// // response = client.createIdentityLinkResponse(request);
// // }
//
//
// return response.getAssertion();
//
// }
/**
* Builds the szrgw:GetIdentityLinkRequest für the SZR-GW
* @param givenname
* @param familyname
* @param birthday
* @return
*/
private static Document buildGetIdentityLinkRequest(X509Certificate cert) {
try {
byte[] certbyte = cert.getEncoded();
String certstring = Base64.encode(certbyte);
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element getIdentityLink = doc.createElementNS(SZRGWConstants.SZRGW_REQUEST_NS, "szrgw:GetIdentityLinkRequest");
getIdentityLink.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:szrgw", SZRGWConstants.SZRGW_REQUEST_NS);
doc.appendChild(getIdentityLink);
Element x509certificate = doc.createElementNS(SZRGWConstants.SZRGW_REQUEST_NS, "szrgw:X509Certificate");
getIdentityLink.appendChild(x509certificate);
Text certbase64 = doc.createTextNode(certstring);
x509certificate.appendChild(certbase64);
return doc;
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (CertificateEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* Checks a parameter.
* @param param parameter
* @return true if the parameter is null or empty
*/
private boolean isEmpty(String param) {
return param == null || param.length() == 0;
}
}