aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2015-09-14 13:29:32 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2015-09-14 13:29:32 +0200
commit76bae60e9bda1acb7ee0e3d45ab187749d16bf82 (patch)
treeba22e87aeee1330e70e702dcfb4612fd951e6c7a /id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
parent1131cdf040e608c3f79dd8987ec3b8444fc9bf0d (diff)
downloadmoa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.tar.gz
moa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.tar.bz2
moa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.zip
move citizen-card authentication and validation (Security-layer communication) to discrete module
Diffstat (limited to 'id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java')
-rw-r--r--id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java1371
1 files changed, 1371 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
new file mode 100644
index 000000000..0850bb676
--- /dev/null
+++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
@@ -0,0 +1,1371 @@
+package at.gv.egovernment.moa.id.auth;
+
+
+import iaik.asn1.ObjectID;
+import iaik.x509.X509Certificate;
+import iaik.x509.X509ExtensionInitException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.cert.CertificateException;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.xpath.XPathAPI;
+import org.opensaml.xml.util.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder;
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
+import at.gv.egovernment.moa.id.auth.builder.GetIdentityLinkFormBuilder;
+import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilder;
+import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.BKUException;
+import at.gv.egovernment.moa.id.auth.exception.BuildException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.exception.ParseException;
+import at.gv.egovernment.moa.id.auth.exception.ServiceException;
+import at.gv.egovernment.moa.id.auth.exception.ValidateException;
+import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker;
+import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser;
+import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser;
+import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser;
+import at.gv.egovernment.moa.id.auth.validator.CreateXMLSignatureResponseValidator;
+import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator;
+import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator;
+import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWConstants;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.data.MISMandate;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.util.XMLUtil;
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.FileUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
+import at.gv.egovernment.moa.util.StringUtils;
+
+/**
+ * API for MOA ID Authentication Service.<br> {@link AuthenticationSession} is
+ * stored in a session store and retrieved by giving the session ID.
+ *
+ * @author Paul Ivancsics
+ * @version $Id: AuthenticationServer.java 1273 2012-02-27 14:50:18Z kstranacher
+ * $
+ */
+public class AuthenticationServer extends BaseAuthenticationServer {
+
+ /**
+ * single instance
+ */
+ private static AuthenticationServer instance;
+
+ /**
+ * Returns the single instance of <code>AuthenticationServer</code>.
+ *
+ * @return the single instance of <code>AuthenticationServer</code>
+ */
+ public static AuthenticationServer getInstance() {
+ if (instance == null)
+ instance = new AuthenticationServer();
+ return instance;
+ }
+
+ /**
+ * Constructor for AuthenticationServer.
+ */
+ public AuthenticationServer() {
+ super();
+ }
+
+
+ /**
+ * Processes the beginning of an authentication session.
+ * <ul>
+ * <li>Starts an authentication session</li>
+ * <li>Creates an <code>&lt;InfoboxReadRequest&gt;</code></li>
+ * <li>Creates an HTML form for querying the identity link from the security
+ * layer implementation. <br>
+ * Form parameters include
+ * <ul>
+ * <li>the <code>&lt;InfoboxReadRequest&gt;</code></li>
+ * <li>the data URL where the security layer implementation sends it
+ * response to</li>
+ * </ul>
+ * </ul>
+ *
+ * @param authURL URL of the servlet to be used as data URL
+ * @param target "Gesch&auml;ftsbereich" of the online application requested
+ * @param targetFriendlyName Friendly name of the target if the target is configured via
+ * configuration
+ * @param oaURL online application URL requested
+ * @param bkuURL URL of the "B&uuml;rgerkartenumgebung" to be used; may be
+ * <code>null</code>; in this case, the default location will be
+ * used
+ * @param useMandate Indicates if mandate is used or not
+ * @param templateURL URL providing an HTML template for the HTML form generated
+ * @param templateMandteURL URL providing an HTML template for the HTML form generated
+ * (for signing in mandates mode)
+ * @param req determines the protocol used
+ * @param sourceID
+ * @return HTML form
+ * @throws AuthenticationException
+ * @see GetIdentityLinkFormBuilder
+ * @see InfoboxReadRequestBuilder
+ */
+ public String startAuthentication(AuthenticationSession session, HttpServletRequest req) throws WrongParametersException,
+ AuthenticationException, ConfigurationException, BuildException {
+
+ if (session == null) {
+ throw new AuthenticationException("auth.18", new Object[]{});
+ }
+
+ //load OnlineApplication configuration
+ OAAuthParameter oaParam =
+ AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+ if (oaParam == null)
+ throw new AuthenticationException("auth.00", new Object[]{session.getPublicOAURLPrefix()});
+
+ //load Template
+ String template = null;
+ if (session.getTemplateURL() != null) {
+ try {
+
+ template = new String(FileUtils.readURL(session.getTemplateURL()));
+ } catch (IOException ex) {
+ throw new AuthenticationException("auth.03", new Object[]{
+ session.getTemplateURL(), ex.toString()}, ex);
+ }
+ }
+
+ String infoboxReadRequest = "";
+
+ String domainIdentifier = AuthConfigurationProviderFactory.getInstance().getSSOTagetIdentifier().trim();
+ if (MiscUtil.isEmpty(domainIdentifier) && session.isSsoRequested()) {
+ //do not use SSO if no Target is set
+ Logger.warn("NO SSO-Target found in configuration. Single Sign-On is deaktivated!");
+ session.setSsoRequested(false);
+
+ }
+
+ if (session.isSsoRequested()) {
+ Logger.info("SSO Login requested");
+ //load identityLink with SSO Target
+ boolean isbuisness = false;
+
+ if (domainIdentifier.startsWith(PREFIX_WPBK)) {
+
+ isbuisness = true;
+
+ } else {
+ isbuisness = false;
+
+ }
+
+ //build ReadInfobox request
+ infoboxReadRequest = new InfoboxReadRequestBuilder().build(
+ isbuisness, domainIdentifier);
+
+ } else {
+ Logger.info("Non-SSO Login requested");
+ //build ReadInfobox request
+ infoboxReadRequest = new InfoboxReadRequestBuilder().build(
+ oaParam.getBusinessService(), oaParam
+ .getIdentityLinkDomainIdentifier());
+
+ }
+
+
+ String dataURL = new DataURLBuilder().buildDataURL(
+ session.getAuthURL(), REQ_VERIFY_IDENTITY_LINK, session
+ .getSessionID());
+
+ //removed in MOAID 2.0
+ String pushInfobox = "";
+
+ // VerifyInfoboxParameters verifyInfoboxParameters = oaParam
+ // .getVerifyInfoboxParameters();
+ // if (verifyInfoboxParameters != null) {
+ // pushInfobox = verifyInfoboxParameters.getPushInfobox();
+ // session.setPushInfobox(pushInfobox);
+ // }
+
+ //build CertInfo request
+ //removed in MOA-ID 2.0
+ // String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder()
+ // .build();
+ // String certInfoDataURL = new DataURLBuilder()
+ // .buildDataURL(session.getAuthURL(), REQ_START_AUTHENTICATION,
+ // session.getSessionID());
+
+ //get Applet Parameters
+ String appletwidth = req.getParameter(PARAM_APPLET_WIDTH);
+ String appletheigth = req.getParameter(PARAM_APPLET_HEIGTH);
+ appletheigth = StringEscapeUtils.escapeHtml(appletheigth);
+ appletwidth = StringEscapeUtils.escapeHtml(appletwidth);
+
+ //TODO: cleanup before MOA-ID 2.1 release
+ try {
+ String htmlForm = new GetIdentityLinkFormBuilder().build(template,
+ session.getBkuURL(), infoboxReadRequest, dataURL, null,
+ null, pushInfobox, oaParam, appletheigth, appletwidth);
+
+ return htmlForm;
+
+ } catch (BuildException e) {
+ throw new BuildException("builder.07", null, e);
+
+ }
+ }
+
+ /**
+ * Processes an <code>&lt;InfoboxReadResponse&gt;</code> sent by the security layer implementation.<br>
+ * <ul>
+ * <li>Validates given <code>&lt;InfoboxReadResponse&gt;</code></li>
+ * <li>Parses identity link enclosed in <code>&lt;InfoboxReadResponse&gt;</code></li>
+ * <li>Verifies identity link by calling the MOA SP component</li>
+ * <li>Checks certificate authority of identity link</li>
+ * <li>Stores identity link in the session</li>
+ * <li>Verifies all additional infoboxes returned from the BKU</li>
+ * <li>Creates an authentication block to be signed by the user</li>
+ * <li>Creates and returns a <code>&lt;CreateXMLSignatureRequest&gt;</code> containg the authentication block, meant
+ * to be returned to the security layer implementation</li>
+ * </ul>
+ *
+ * @param sessionID
+ * ID of associated authentication session data
+ * @param infoboxReadResponseParameters
+ * The parameters from the response returned from the BKU including the
+ * <code>&lt;InfoboxReadResponse&gt;</code>
+ * @return String "found!" in case the identity link could be retrieved and successfully validated, {@code null} in
+ * case the identity link could not be retrieved (indicates that the card did not contain an identity link
+ * which might indicate a foreign identity). Note that failing to parse or failing to validate the identity
+ * link results in an Exception being thrown.
+ * @throws BKUException
+ */
+ public String verifyIdentityLink(IRequest pendingReq, AuthenticationSession session,
+ Map<String, String> infoboxReadResponseParameters) throws AuthenticationException,
+ BuildException, ParseException, ConfigurationException,
+ ValidateException, ServiceException, BKUException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_IDENTITY_LINK, PARAM_SESSIONID});
+
+ String xmlInfoboxReadResponse = (String) infoboxReadResponseParameters
+ .get(PARAM_XMLRESPONSE);
+
+ if (isEmpty(xmlInfoboxReadResponse))
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_IDENTITY_LINK, PARAM_XMLRESPONSE});
+
+ AuthConfiguration authConf = AuthConfigurationProviderFactory
+ .getInstance();
+
+ // check if an identity link was found
+ // Errorcode 2911 von Trustdesk BKU (nicht spezifikationskonform
+ // (SL1.2))
+ // CharSequence se = "ErrorCode>2911".substring(0);
+ // boolean b = xmlInfoboxReadResponse.contains(se);
+ String se = "ErrorCode>2911";
+ int b = xmlInfoboxReadResponse.indexOf(se);
+ if (b != -1) { // no identity link found
+ Logger
+ .info("Es konnte keine Personenbindung auf der Karte gefunden werden. Versuche Anmeldung als auslaendische eID.");
+ return null;
+ }
+ // spezifikationsgemaess (SL1.2) Errorcode
+ se = "ErrorCode>4002";
+ // b = xmlInfoboxReadResponse.contains(se);
+ b = xmlInfoboxReadResponse.indexOf(se);
+ if (b != -1) { // Unbekannter Infoboxbezeichner
+ Logger
+ .info("Unbekannter Infoboxbezeichner. Versuche Anmeldung als auslaendische eID.");
+ return null;
+ }
+
+ // parses the <InfoboxReadResponse>
+ IdentityLink identityLink = new InfoboxReadResponseParser(
+ xmlInfoboxReadResponse).parseIdentityLink();
+ // validates the identity link
+ IdentityLinkValidator.getInstance().validate(identityLink);
+ // builds a <VerifyXMLSignatureRequest> for a call of MOA-SP
+ Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder()
+ .build(identityLink, authConf
+ .getMoaSpIdentityLinkTrustProfileID(pendingReq.getOnlineApplicationConfiguration().isUseIDLTestTrustStore()));
+
+ // invokes the call
+ Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker()
+ .verifyXMLSignature(domVerifyXMLSignatureRequest);
+ // parses the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser(
+ domVerifyXMLSignatureResponse).parseData();
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+
+ // validates the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponseValidator.getInstance().validate(
+ verifyXMLSignatureResponse,
+ authConf.getIdentityLinkX509SubjectNames(),
+ VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK,
+ oaParam);
+
+ session.setIdentityLink(identityLink);
+ // now validate the extended infoboxes
+
+ //Removed in MOA-ID 2.0
+ //verifyInfoboxes(session, infoboxReadResponseParameters, false);
+
+ MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),
+ pendingReq, MOAIDEventConstants.AUTHPROCESS_IDL_VALIDATED);
+
+ return "found!";
+ }
+
+ /**
+ * Processes an <code>&lt;InfoboxReadResponse&gt;</code> sent by the
+ * security layer implementation.<br>
+ * <ul>
+ * <li>Validates given <code>&lt;InfoboxReadResponse&gt;</code></li>
+ * <li>Parses identity link enclosed in
+ * <code>&lt;InfoboxReadResponse&gt;</code></li>
+ * <li>Verifies identity link by calling the MOA SP component</li>
+ * <li>Checks certificate authority of identity link</li>
+ * <li>Stores identity link in the session</li>
+ * <li>Verifies all additional infoboxes returned from the BKU</li>
+ * <li>Creates an authentication block to be signed by the user</li>
+ * <li>Creates and returns a <code>&lt;CreateXMLSignatureRequest&gt;</code>
+ * containg the authentication block, meant to be returned to the security
+ * layer implementation</li>
+ * </ul>
+ *
+ * @param sessionID ID of associated authentication session data
+ * @param infoboxReadResponseParameters The parameters from the response returned from the BKU
+ * including the <code>&lt;InfoboxReadResponse&gt;</code>
+ * @return String representation of the
+ * <code>&lt;CreateXMLSignatureRequest&gt;</code>
+ */
+ public String verifyCertificate(AuthenticationSession session,
+ X509Certificate certificate) throws AuthenticationException,
+ BuildException, ParseException, ConfigurationException,
+ ValidateException, ServiceException, MOAIDException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID});
+
+ // check if person is a Organwalter
+ // if true - don't show bPK in AUTH Block
+ try {
+ for (ObjectID OWid : MOAIDAuthConstants.OW_LIST) {
+ if (certificate.getExtension(OWid) != null) {
+ session.setOW(true);
+ }
+
+ }
+
+ } catch (X509ExtensionInitException e) {
+ Logger.warn("Certificate extension is not readable.");
+ session.setOW(false);
+ }
+
+ AuthConfiguration authConf = AuthConfigurationProviderFactory
+ .getInstance();
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+
+ String returnvalue = getCreateXMLSignatureRequestAuthBlockOrRedirect(session,
+ authConf, oaParam);
+
+ return returnvalue;
+ }
+
+ /**
+ * Processes an <code>Mandate</code> sent by the MIS.<br>
+ * <ul>
+ * <li>Validates given <code>Mandate</code></li>
+ * <li>Verifies Mandate by calling the MOA SP component</li>
+ * <li>Creates an authentication block to be signed by the user</li>
+ * <li>Creates and returns a <code>&lt;CreateXMLSignatureRequest&gt;</code>
+ * containg the authentication block, meant to be returned to the security
+ * layer implementation</li>
+ * </ul>
+ * @param pendingReq
+ *
+ * @param sessionID ID of associated authentication session data
+ * @param infoboxReadResponseParameters The parameters from the response returned from the BKU
+ * including the <code>&lt;InfoboxReadResponse&gt;</code>
+ * @return String representation of the
+ * <code>&lt;CreateXMLSignatureRequest&gt;</code>
+ */
+ public void verifyMandate(AuthenticationSession session, MISMandate mandate)
+ throws AuthenticationException, BuildException, ParseException,
+ ConfigurationException, ValidateException, ServiceException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ GET_MIS_SESSIONID, PARAM_SESSIONID});
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+
+ try {
+ // sets the extended SAML attributes for OID (Organwalter)
+ setExtendedSAMLAttributeForMandatesOID(session, mandate, oaParam
+ .getBusinessService());
+
+ validateExtendedSAMLAttributeForMandates(session, mandate, oaParam.getBusinessService());
+
+
+ } catch (SAXException e) {
+ throw new AuthenticationException("auth.15",
+ new Object[]{GET_MIS_SESSIONID}, e);
+ } catch (IOException e) {
+ throw new AuthenticationException("auth.15",
+ new Object[]{GET_MIS_SESSIONID}, e);
+ } catch (ParserConfigurationException e) {
+ throw new AuthenticationException("auth.15",
+ new Object[]{GET_MIS_SESSIONID}, e);
+ } catch (TransformerException e) {
+ throw new AuthenticationException("auth.15",
+ new Object[]{GET_MIS_SESSIONID}, e);
+ }
+
+ }
+
+ /**
+ * @param session
+ * @param authConf
+ * @param oaParam
+ * @return
+ * @throws ConfigurationException
+ * @throws BuildException
+ * @throws ValidateException
+ */
+ public String getCreateXMLSignatureRequestAuthBlockOrRedirect(
+ AuthenticationSession session, AuthConfiguration authConf,
+ OAAuthParameter oaParam) throws ConfigurationException,
+ BuildException, ValidateException {
+
+ // // check for intermediate processing of the infoboxes
+ // if (session.isValidatorInputPending())
+ // return "Redirect to Input Processor";
+
+ if (authConf == null)
+ authConf = AuthConfigurationProviderFactory.getInstance();
+ if (oaParam == null)
+ oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(
+ session.getPublicOAURLPrefix());
+
+ // builds the AUTH-block
+ String authBlock = buildAuthenticationBlock(session, oaParam);
+
+ // builds the <CreateXMLSignatureRequest>
+ List<String> transformsInfos = authConf.getTransformsInfos();
+
+ String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder()
+ .build(authBlock, oaParam.getKeyBoxIdentifier(),
+ transformsInfos);
+ return createXMLSignatureRequest;
+ }
+
+ /**
+ * Returns an CreateXMLSignatureRequest for signing the ERnP statement.<br>
+ * <ul>
+ * <li>Creates an CreateXMLSignatureRequest to be signed by the user</li>
+ * </ul>
+ *
+ * @param sessionID ID of associated authentication session data
+ * @param cert The certificate from the user
+ * @return String representation of the
+ * <code>&lt;CreateXMLSignatureRequest&gt;</code>
+ */
+ public String createXMLSignatureRequestForeignID(AuthenticationSession session,
+ X509Certificate cert) throws AuthenticationException,
+ BuildException, ParseException, ConfigurationException,
+ ValidateException, ServiceException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID});
+
+ AuthConfiguration authConf = AuthConfigurationProviderFactory
+ .getInstance();
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+
+ return getCreateXMLSignatureRequestForeigID(session, authConf, oaParam,
+ cert);
+ }
+
+ public String getCreateXMLSignatureRequestForeigID(
+ AuthenticationSession session, AuthConfiguration authConf,
+ OAAuthParameter oaParam, X509Certificate cert)
+ throws ConfigurationException {
+
+ // // check for intermediate processing of the infoboxes
+ // if (session.isValidatorInputPending())
+ // return "Redirect to Input Processor";
+
+ if (authConf == null)
+ authConf = AuthConfigurationProviderFactory.getInstance();
+ if (oaParam == null)
+ oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(
+ session.getPublicOAURLPrefix());
+
+ Principal subject = cert.getSubjectDN();
+
+ String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder()
+ .buildForeignID(subject.toString(), oaParam, session);
+ return createXMLSignatureRequest;
+ }
+
+// /**
+// * Processes an <code>&lt;CreateXMLSignatureResponse&gt;</code> sent by the
+// * security layer implementation.<br>
+// * <ul>
+// * <li>Validates given <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+// * <li>Parses response enclosed in
+// * <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+// * <li>Verifies signature by calling the MOA SP component</li>
+// * <li>Returns the signer certificate</li>
+// * </ul>
+// *
+// * @param sessionID ID of associated authentication session data
+// * @param createXMLSignatureResponseParameters The parameters from the response returned from the BKU
+// * including the <code>&lt;CreateXMLSignatureResponse&gt;</code>
+// * @throws BKUException
+// */
+// public X509Certificate verifyXMLSignature(String sessionID,
+// Map<String, String> createXMLSignatureResponseParameters)
+// throws AuthenticationException, BuildException, ParseException,
+// ConfigurationException, ValidateException, ServiceException, BKUException {
+//
+// if (isEmpty(sessionID))
+// throw new AuthenticationException("auth.10", new Object[]{
+// REQ_GET_FOREIGN_ID, PARAM_SESSIONID});
+//
+// String xmlCreateXMLSignatureResponse = (String) createXMLSignatureResponseParameters
+// .get(PARAM_XMLRESPONSE);
+//
+// if (isEmpty(xmlCreateXMLSignatureResponse))
+// throw new AuthenticationException("auth.10", new Object[]{
+// REQ_GET_FOREIGN_ID, PARAM_XMLRESPONSE});
+//
+// AuthConfiguration authConf = AuthConfigurationProviderFactory
+// .getInstance();
+//
+// // parses the <CreateXMLSignatureResponse>
+// CreateXMLSignatureResponseParser p = new CreateXMLSignatureResponseParser(
+// xmlCreateXMLSignatureResponse);
+// CreateXMLSignatureResponse createXMLSignatureResponse = p
+// .parseResponseDsig();
+//
+// // builds a <VerifyXMLSignatureRequest> for a call of MOA-SP
+// Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder()
+// .buildDsig(createXMLSignatureResponse, authConf
+// .getMoaSpAuthBlockTrustProfileID());
+//
+// // invokes the call
+// Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker()
+// .verifyXMLSignature(domVerifyXMLSignatureRequest);
+//
+// // parses the <VerifyXMLSignatureResponse>
+// VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser(
+// domVerifyXMLSignatureResponse).parseData();
+//
+// return verifyXMLSignatureResponse.getX509certificate();
+//
+// }
+
+ /**
+ * Processes an <code>&lt;CreateXMLSignatureResponse&gt;</code> sent by the
+ * security layer implementation.<br>
+ * <ul>
+ * <li>Validates given <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Parses response enclosed in
+ * <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Verifies signature by calling the MOA SP component</li>
+ * <li>Returns the signer certificate</li>
+ * </ul>
+ * @param pendingReq
+ *
+ * @param sessionID ID of associated authentication session data
+ * @param readInfoboxResponseParameters The parameters from the response returned from the BKU
+ * including the <code>&lt;ReadInfoboxResponse&gt;</code>
+ * @throws BKUException
+ */
+ public X509Certificate getCertificate(IRequest pendingReq, String sessionID,
+ Map<String, String> readInfoboxResponseParameters) throws AuthenticationException,
+ BuildException, ParseException, ConfigurationException,
+ ValidateException, ServiceException, BKUException {
+
+ if (isEmpty(sessionID))
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID});
+
+ String xmlReadInfoboxResponse = (String) readInfoboxResponseParameters
+ .get(PARAM_XMLRESPONSE);
+
+ if (isEmpty(xmlReadInfoboxResponse))
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_CERTIFICATE, PARAM_XMLRESPONSE});
+
+ // parses the <CreateXMLSignatureResponse>
+ InfoboxReadResponseParser p = new InfoboxReadResponseParser(
+ xmlReadInfoboxResponse);
+ X509Certificate cert = p.parseCertificate();
+
+ MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),
+ pendingReq, MOAIDEventConstants.AUTHPROCESS_CERTIFICATE_VALIDATED);
+
+ return cert;
+
+ }
+
+ /**
+ * Builds an authentication block <code>&lt;saml:Assertion&gt;</code> from
+ * given session data.
+ *
+ * @param session authentication session
+ * @return <code>&lt;saml:Assertion&gt;</code> as a String
+ * @throws BuildException If an error occurs on serializing an extended SAML attribute
+ * to be appended to the AUTH-Block.
+ */
+ private String buildAuthenticationBlock(AuthenticationSession session,
+ OAAuthParameter oaParam) throws BuildException {
+
+ IdentityLink identityLink = session.getIdentityLink();
+ String issuer = identityLink.getName();
+ String gebDat = identityLink.getDateOfBirth();
+
+ String identificationValue = null;
+ String identificationType = null;
+
+ //set empty AuthBlock BPK in case of OW or SSO or bpk is not requested
+ if (session.isOW() || session.isSsoRequested() || oaParam.isRemovePBKFromAuthBlock()) {
+ identificationType = "";
+ identificationValue = "";
+
+ } else if (identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+
+ if (oaParam.getBusinessService()) {
+
+ String bpkBase64 = new BPKBuilder().buildWBPK(identityLink
+ .getIdentificationValue(), oaParam.getIdentityLinkDomainIdentifier());
+ identificationValue = bpkBase64;
+
+ if (oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_WBPK + "+"))
+ identificationType = oaParam.getIdentityLinkDomainIdentifier();
+ else
+ identificationType = Constants.URN_PREFIX_WBPK + "+" + oaParam.getIdentityLinkDomainIdentifier();
+
+ } else {
+ String bpkBase64 = new BPKBuilder().buildBPK(identityLink
+ .getIdentificationValue(), session.getTarget());
+ identificationValue = bpkBase64;
+ identificationType = Constants.URN_PREFIX_CDID + "+" + session.getTarget();
+ }
+
+
+ } else {
+ identificationValue = identityLink.getIdentificationValue();
+ identificationType = identityLink.getIdentificationType();
+
+ }
+
+ String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar
+ .getInstance());
+ session.setIssueInstant(issueInstant);
+ String authURL = session.getAuthURL();
+ String target = session.getTarget();
+ String targetFriendlyName = session.getTargetFriendlyName();
+
+ // Bug #485
+ // (https://egovlabs.gv.at/tracker/index.php?func=detail&aid=485&group_id=6&atid=105)
+ // String oaURL = session.getPublicOAURLPrefix();
+
+ List<ExtendedSAMLAttribute> extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH();
+
+
+ if (session.isSsoRequested()) {
+ String oaURL = new String();
+ try {
+ oaURL = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix();
+
+ if (MiscUtil.isNotEmpty(oaURL))
+ oaURL = oaURL.replaceAll("&", "&amp;");
+
+ } catch (ConfigurationException e) {
+ }
+ String authBlock = new AuthenticationBlockAssertionBuilder()
+ .buildAuthBlockSSO(issuer, issueInstant, authURL, target,
+ targetFriendlyName, identificationValue,
+ identificationType, oaURL, gebDat,
+ extendedSAMLAttributes, session, oaParam);
+ return authBlock;
+
+ } else {
+ String oaURL = session.getPublicOAURLPrefix().replaceAll("&", "&amp;");
+ String authBlock = new AuthenticationBlockAssertionBuilder()
+ .buildAuthBlock(issuer, issueInstant, authURL, target,
+ targetFriendlyName, identificationValue,
+ identificationType, oaURL, gebDat,
+ extendedSAMLAttributes, session, oaParam);
+ return authBlock;
+ }
+ }
+
+
+ /**
+ * Verifies the infoboxes (except of the identity link infobox) returned by
+ * the BKU by calling appropriate validator classes.
+ *
+ * @param session The actual authentication session.
+ * @param mandate The Mandate from the MIS
+ * @throws AuthenticationException
+ * @throws ConfigurationException
+ * @throws TransformerException
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ */
+ private void validateExtendedSAMLAttributeForMandates(
+ AuthenticationSession session, MISMandate mandate,
+ boolean business)
+ throws ValidateException, ConfigurationException, SAXException,
+ IOException, ParserConfigurationException, TransformerException {
+
+ ExtendedSAMLAttribute[] extendedSAMLAttributes = addExtendedSamlAttributes(
+ mandate, business, false);
+
+ int length = extendedSAMLAttributes.length;
+ for (int i = 0; i < length; i++) {
+ ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i];
+
+ verifySAMLAttribute(samlAttribute, i, "MISService",
+ "MISService");
+
+ }
+ }
+
+ /**
+ * Verifies the infoboxes (except of the identity link infobox) returned by
+ * the BKU by calling appropriate validator classes.
+ *
+ * @param session The actual authentication session.
+ * @param mandate The Mandate from the MIS
+ * @throws AuthenticationException
+ * @throws ConfigurationException
+ * @throws TransformerException
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ */
+ private void setExtendedSAMLAttributeForMandatesOID(
+ AuthenticationSession session, MISMandate mandate, boolean business)
+ throws ValidateException, ConfigurationException, SAXException,
+ IOException, ParserConfigurationException, TransformerException {
+
+ ExtendedSAMLAttribute[] extendedSamlAttributes = addExtendedSamlAttributesOID(
+ mandate, business);
+
+ AddAdditionalSAMLAttributes(session, extendedSamlAttributes,
+ "MISService", "MISService");
+
+ }
+
+ /**
+ * Adds given SAML Attributes to the current session. They will be appended
+ * to the final SAML Assertion or the AUTH block. If the attributes are
+ * already in the list, they will be replaced.
+ *
+ * @param session The current session
+ * @param extendedSAMLAttributes The SAML attributes to add
+ * @param identifier The infobox identifier for debug purposes
+ * @param friendlyNam The friendly name of the infobox for debug purposes
+ */
+ private static void AddAdditionalSAMLAttributes(
+ AuthenticationSession session,
+ ExtendedSAMLAttribute[] extendedSAMLAttributes, String identifier,
+ String friendlyName) throws ValidateException {
+ if (extendedSAMLAttributes == null)
+ return;
+ List<ExtendedSAMLAttribute> oaAttributes = session.getExtendedSAMLAttributesOA();
+ if (oaAttributes == null)
+ oaAttributes = new Vector<ExtendedSAMLAttribute>();
+ List<ExtendedSAMLAttribute> authAttributes = session.getExtendedSAMLAttributesAUTH();
+ if (authAttributes == null)
+ authAttributes = new Vector<ExtendedSAMLAttribute>();
+ int length = extendedSAMLAttributes.length;
+ for (int i = 0; i < length; i++) {
+ ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i];
+
+ Object value = verifySAMLAttribute(samlAttribute, i, identifier,
+ friendlyName);
+
+ if ((value instanceof String) || (value instanceof Element)) {
+ switch (samlAttribute.getAddToAUTHBlock()) {
+ case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY:
+ replaceExtendedSAMLAttribute(authAttributes, samlAttribute);
+ break;
+ case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK:
+ replaceExtendedSAMLAttribute(authAttributes, samlAttribute);
+ replaceExtendedSAMLAttribute(oaAttributes, samlAttribute);
+ break;
+ case ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK:
+ replaceExtendedSAMLAttribute(oaAttributes, samlAttribute);
+ break;
+ default:
+ Logger
+ .info("Invalid return value from method \"getAddToAUTHBlock()\" ("
+ + samlAttribute.getAddToAUTHBlock()
+ + ") in SAML attribute number "
+ + (i + 1)
+ + " for infobox " + identifier);
+ throw new ValidateException("validator.47", new Object[]{
+ friendlyName, String.valueOf((i + 1))});
+ }
+ } else {
+ Logger
+ .info("The type of SAML-Attribute number "
+ + (i + 1)
+ + " returned from "
+ + identifier
+ + "-infobox validator is not valid. Must be either \"java.Lang.String\""
+ + " or \"org.w3c.dom.Element\"");
+ throw new ValidateException("validator.46", new Object[]{
+ identifier, String.valueOf((i + 1))});
+ }
+ }
+ session.setExtendedSAMLAttributesAUTH(authAttributes);
+ session.setExtendedSAMLAttributesOA(oaAttributes);
+ }
+
+ /**
+ * Adds the AUTH block related SAML attributes to the validation result.
+ * This is needed always before the AUTH block is to be signed, because the
+ * name of the mandator has to be set
+ *
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ * @throws TransformerException
+ */
+
+ protected static ExtendedSAMLAttribute[] addExtendedSamlAttributes(
+ MISMandate mandate, boolean business, boolean provideStammzahl)
+ throws SAXException, IOException, ParserConfigurationException,
+ TransformerException {
+ Vector<ExtendedSAMLAttribute> extendedSamlAttributes = new Vector<ExtendedSAMLAttribute>();
+
+ extendedSamlAttributes.clear();
+
+ // Name
+ Element domMandate = mandateToElement(mandate);
+ Element nameSpaceNode = domMandate.getOwnerDocument().createElement(
+ "NameSpaceNode");
+ nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX,
+ Constants.PD_NS_URI);
+ nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.MANDATE_POSTFIX,
+ SZRGWConstants.MANDATE_NS);
+
+ Element mandator = (Element) XPathAPI.selectSingleNode(domMandate,
+ "//md:Mandate/md:Mandator", nameSpaceNode);
+
+ // Mandate
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_RAW, domMandate,
+ SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK));
+
+ // (w)bpk
+ String wbpk = ParepUtils.extractMandatorWbpk(mandator);
+ if (!ParepUtils.isEmpty(wbpk)) {
+ if (!ParepUtils.isPhysicalPerson(mandator)) {
+ String idType = ParepUtils
+ .extractMandatorIdentificationType(mandator);
+ if (!ParepUtils.isEmpty(idType)
+ && idType.startsWith(Constants.URN_PREFIX_BASEID)) {
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_CB_BASE_ID,
+ ParepUtils.getRegisterString(idType) + ": " + wbpk,
+ SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY));
+ }
+ } else if (business) {
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_WBPK, wbpk,
+ SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY));
+ }
+ }
+
+ ExtendedSAMLAttribute[] ret = new ExtendedSAMLAttribute[extendedSamlAttributes
+ .size()];
+ extendedSamlAttributes.copyInto(ret);
+ Logger.debug("ExtendedSAML Attributes: " + ret.length);
+ return ret;
+
+ }
+
+ /**
+ * Adds the AUTH block related SAML attributes to the validation result.
+ * This is needed always before the AUTH block is to be signed, because the
+ * name of the mandator has to be set
+ *
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ * @throws TransformerException
+ */
+ private static ExtendedSAMLAttribute[] addExtendedSamlAttributesOID(
+ MISMandate mandate, boolean business) throws SAXException,
+ IOException, ParserConfigurationException, TransformerException {
+
+ Vector<ExtendedSAMLAttribute> extendedSamlAttributes = new Vector<ExtendedSAMLAttribute>();
+
+ extendedSamlAttributes.clear();
+
+ // RepresentationType
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_REPRESENTATIONTYPE,
+ EXT_SAML_MANDATE_REPRESENTATIONTEXT,
+ SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK));
+
+ String oid = mandate.getProfRep();
+
+ if (oid != null) {
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_OID, oid,
+ SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK));
+ String oidDescription = mandate.getTextualDescriptionOfOID();
+ extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(
+ EXT_SAML_MANDATE_OIDTEXTUALDESCRIPTION,
+ oidDescription, SZRGWConstants.MANDATE_NS,
+ ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK));
+
+ }
+
+ ExtendedSAMLAttribute[] ret = new ExtendedSAMLAttribute[extendedSamlAttributes
+ .size()];
+ extendedSamlAttributes.copyInto(ret);
+ Logger.debug("ExtendedSAML Attributes: " + ret.length);
+ return ret;
+
+ }
+
+ /**
+ * @param mandate
+ * @return
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ */
+ private static Element mandateToElement(MISMandate mandate)
+ throws SAXException, IOException, ParserConfigurationException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(mandate
+ .getMandate());
+ Document doc = DOMUtils.parseDocumentSimple(bais);
+ bais.close();
+ return doc.getDocumentElement();
+ }
+
+ protected static void replaceExtendedSAMLAttribute(List<ExtendedSAMLAttribute> attributes,
+ ExtendedSAMLAttribute samlAttribute) {
+ if (null == attributes) {
+ attributes = new Vector<ExtendedSAMLAttribute>();
+ } else {
+ String id = samlAttribute.getName();
+ int length = attributes.size();
+ for (int i = 0; i < length; i++) {
+ ExtendedSAMLAttribute att = (ExtendedSAMLAttribute) attributes
+ .get(i);
+ if (id.equals(att.getName())) {
+ // replace attribute
+ attributes.set(i, samlAttribute);
+ return;
+ }
+ }
+ attributes.add(samlAttribute);
+ }
+ }
+
+ /**
+ * Processes a <code>&lt;CreateXMLSignatureResponse&gt;</code> sent by the
+ * security layer implementation.<br>
+ * <ul>
+ * <li>Validates given <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Parses <code>&lt;CreateXMLSignatureResponse&gt;</code> for error
+ * codes</li>
+ * <li>Parses authentication block enclosed in
+ * <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Verifies authentication block by calling the MOA SP component</li>
+ * <li>Creates authentication data</li>
+ * <li>Creates a corresponding SAML artifact</li>
+ * <li>Stores authentication data in the authentication data store indexed
+ * by the SAML artifact</li>
+ * <li>Deletes authentication session</li>
+ * <li><strike>Returns the SAML artifact, encoded BASE64</strike><br/>New id of the authenticated MOA session or {@code null} in case of mandate mode (???)</li>
+ * </ul>
+ * @param pendingReq
+ *
+ * @param sessionID session ID of the running authentication session
+ * @param xmlCreateXMLSignatureReadResponse String representation of the
+ * <code>&lt;CreateXMLSignatureResponse&gt;</code>
+ * @return <strike>SAML artifact needed for retrieving authentication data, encoded
+ * BASE64</strike><br/>New id of the authenticated MOA session or {@code null} in case of mandate mode (???)
+ * @throws BKUException
+ */
+ public void verifyAuthenticationBlock(IRequest pendingReq, AuthenticationSession session,
+ String xmlCreateXMLSignatureReadResponse)
+ throws AuthenticationException, BuildException, ParseException,
+ ConfigurationException, ServiceException, ValidateException, BKUException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID});
+ if (isEmpty(xmlCreateXMLSignatureReadResponse))
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE});
+
+ AuthConfiguration authConf = AuthConfigurationProviderFactory
+ .getInstance();
+ // parses <CreateXMLSignatureResponse>
+ CreateXMLSignatureResponse csresp = new CreateXMLSignatureResponseParser(
+ xmlCreateXMLSignatureReadResponse).parseResponse();
+
+ try {
+ String serializedAssertion = DOMUtils.serializeNode(csresp
+ .getSamlAssertion());
+ session.setAuthBlock(serializedAssertion);
+ } catch (TransformerException e) {
+ throw new ParseException("parser.04", new Object[]{
+ REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE});
+ } catch (IOException e) {
+ throw new ParseException("parser.04", new Object[]{
+ REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE});
+ }
+ // validates <CreateXMLSignatureResponse>
+ if (session.isSsoRequested())
+ new CreateXMLSignatureResponseValidator().validateSSO(csresp, session);
+ else
+ new CreateXMLSignatureResponseValidator().validate(csresp, session);
+
+ // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call
+ List<String> vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs();
+ String tpid = authConf.getMoaSpAuthBlockTrustProfileID(pendingReq.getOnlineApplicationConfiguration().isUseAuthBlockTestTestStore());
+ Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp,
+ vtids, tpid);
+ // debug output
+
+ Element domVsresp = null;
+
+ // try {
+ // invokes the call
+ domVsresp = new SignatureVerificationInvoker()
+ .verifyXMLSignature(domVsreq);
+
+ // parses the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponseParser(
+ domVsresp).parseData();
+
+ if (Logger.isTraceEnabled()) {
+ if (domVsresp != null) {
+ try {
+ String xmlVerifyXMLSignatureResponse = DOMUtils
+ .serializeNode(domVsresp, true);
+ Logger.trace(new LogMsg(xmlCreateXMLSignatureReadResponse));
+ Logger.trace(new LogMsg(xmlVerifyXMLSignatureResponse));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Logger.info(new LogMsg(t.getStackTrace()));
+ }
+ }
+ }
+
+ OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance()
+ .getOnlineApplicationParameter(session.getPublicOAURLPrefix());
+
+ // validates the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponseValidator.getInstance().validate(vsresp,
+ null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK,
+ oaParam);
+
+ // Compare AuthBlock Data with information stored in session, especially
+ // date and time
+ CreateXMLSignatureResponseValidator.getInstance().validateSigningDateTime(csresp);
+
+ try {
+ // compares the public keys from the identityLink with the AuthBlock
+ VerifyXMLSignatureResponseValidator.getInstance().validateCertificate(
+ vsresp, session.getIdentityLink());
+
+ } catch ( ValidateException e) {
+ Logger.error("Signature verification error. ", e);
+ Logger.error("Signed Data: " + session.getAuthBlock());
+ try {
+ Logger.error("VerifyRequest: " + DOMUtils.serializeNode(domVsreq));
+ Logger.error("VerifyResponse: " + DOMUtils.serializeNode(domVsresp));
+ } catch (TransformerException e1) {
+ e1.printStackTrace();
+
+ } catch (IOException e1) {
+ e1.printStackTrace();
+
+ }
+
+ throw e;
+ }
+
+ session.setXMLVerifySignatureResponse(vsresp);
+ session.setSignerCertificate(vsresp.getX509certificate());
+ vsresp.setX509certificate(null);
+ session.setForeigner(false);
+
+ //set QAA Level four in case of card authentifcation
+ session.setQAALevel(PVPConstants.STORK_QAA_1_4);
+
+ MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),
+ pendingReq, MOAIDEventConstants.AUTHPROCESS_AUTHBLOCK_VALIDATED);
+
+ MOAReversionLogger.getInstance().logPersonalInformationEvent(pendingReq, session.getIdentityLink()
+ );
+ }
+
+ /**
+ * Processes a <code>&lt;CreateXMLSignatureResponse&gt;</code> sent by the
+ * security layer implementation.<br>
+ * <ul>
+ * <li>Validates given <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Parses <code>&lt;CreateXMLSignatureResponse&gt;</code> for error
+ * codes</li>
+ * <li>Parses authentication block enclosed in
+ * <code>&lt;CreateXMLSignatureResponse&gt;</code></li>
+ * <li>Verifies authentication block by calling the MOA SP component</li>
+ * <li>Creates authentication data</li>
+ * <li>Creates a corresponding SAML artifact</li>
+ * <li>Stores authentication data in the authentication data store indexed
+ * by the SAML artifact</li>
+ * <li>Deletes authentication session</li>
+ * <li>Returns the SAML artifact, encoded BASE64</li>
+ * </ul>
+ *
+ * @param sessionID session ID of the running authentication session
+ * @param xmlCreateXMLSignatureReadResponse String representation of the
+ * <code>&lt;CreateXMLSignatureResponse&gt;</code>
+ * @return SAML artifact needed for retrieving authentication data, encoded
+ * BASE64
+ */
+
+ protected Element createIdentificationBPK(Element mandatePerson,
+ String baseid, String target) throws BuildException {
+ Element identificationBpK = mandatePerson.getOwnerDocument()
+ .createElementNS(Constants.PD_NS_URI, "Identification");
+ Element valueBpK = mandatePerson.getOwnerDocument().createElementNS(
+ Constants.PD_NS_URI, "Value");
+
+ String bpkBase64 = new BPKBuilder().buildBPK(baseid, target);
+ valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
+ bpkBase64));
+ Element typeBpK = mandatePerson.getOwnerDocument().createElementNS(
+ Constants.PD_NS_URI, "Type");
+ typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
+ "urn:publicid:gv.at:cdid+bpk"));
+ identificationBpK.appendChild(valueBpK);
+ identificationBpK.appendChild(typeBpK);
+
+ return identificationBpK;
+
+ }
+
+ protected String getBaseId(Element mandatePerson)
+ throws TransformerException, IOException {
+ NodeList list = mandatePerson.getElementsByTagNameNS(
+ Constants.PD_NS_URI, "Identification");
+ for (int i = 0; i < list.getLength(); i++) {
+ Element identification = (Element) list.item(i);
+ Element type = (Element) identification.getElementsByTagNameNS(
+ Constants.PD_NS_URI, "Type").item(0);
+ if (type.getTextContent().compareToIgnoreCase(
+ "urn:publicid:gv.at:baseid") == 0) {
+ Element value = (Element) identification
+ .getElementsByTagNameNS(Constants.PD_NS_URI, "Value")
+ .item(0);
+ return value.getTextContent();
+ }
+ }
+ return null;
+
+ }
+
+ /**
+ * Gets the foreign authentication data.<br>
+ * <ul>
+ * <li><strong>Creates authentication data</strong></li>
+ * <li>Creates a corresponding SAML artifact</li>
+ * <li>Stores authentication data in the authentication data store indexed
+ * by the SAML artifact</li>
+ * <li>Deletes authentication session</li>
+ * <li><strike>Returns the SAML artifact, encoded BASE64</strike></li>
+ * </ul>
+ *
+ * @param sessionID session ID of the running authentication session
+ * @return String "new Session"
+ */
+ public void getForeignAuthenticationData(AuthenticationSession session)
+ throws AuthenticationException, BuildException, ParseException,
+ ConfigurationException, ServiceException, ValidateException {
+
+ if (session == null)
+ throw new AuthenticationException("auth.10", new Object[]{
+ REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID});
+ VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponse();
+ X509Certificate cert = session.getSignerCertificate();
+ vsresp.setX509certificate(cert);
+
+ session.setXMLVerifySignatureResponse(vsresp);
+ session.setSignerCertificate(vsresp.getX509certificate());
+ vsresp.setX509certificate(null);
+ session.setForeigner(true);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Checks the correctness of SAML attributes and returns its value.
+ *
+ * @param param samlAttribute
+ * @param i the number of the verified attribute for messages
+ * @param identifier the infobox identifier for messages
+ * @param friendlyname the friendly name of the infobox for messages
+ * @return the SAML attribute value (Element or String)
+ */
+ protected static Object verifySAMLAttribute(
+ ExtendedSAMLAttribute samlAttribute, int i, String identifier,
+ String friendlyName) throws ValidateException {
+ String name = samlAttribute.getName();
+
+ if (name == null) {
+ Logger.info("The name of SAML-Attribute number " + (i + 1)
+ + " returned from " + identifier
+ + "-infobox validator is null.");
+ throw new ValidateException("validator.45", new Object[]{
+ friendlyName, "Name", String.valueOf((i + 1)), "null"});
+ }
+ if (name == "") {
+ Logger.info("The name of SAML-Attribute number " + (i + 1)
+ + " returned from " + identifier
+ + "-infobox validator is empty.");
+ throw new ValidateException("validator.45", new Object[]{
+ friendlyName, "Name", String.valueOf((i + 1)), "leer"});
+ }
+ if (samlAttribute.getNameSpace() == null) {
+ Logger.info("The namespace of SAML-Attribute number " + (i + 1)
+ + " returned from " + identifier
+ + "-infobox validator is null.");
+ throw new ValidateException("validator.45",
+ new Object[]{friendlyName, "Namespace",
+ String.valueOf((i + 1)), "null"});
+ }
+ Object value = samlAttribute.getValue();
+ if (value == null) {
+ Logger.info("The value of SAML-Attribute number " + (i + 1)
+ + " returned from " + identifier
+ + "-infobox validator is null.");
+ throw new ValidateException("validator.45", new Object[]{
+ friendlyName, "Wert", String.valueOf((i + 1)), "null"});
+ }
+
+ return value;
+ }
+
+ /**
+ * Extracts an X509 Certificate out of an XML signagture element
+ *
+ * @param signedXML XML signature element
+ * @return X509Certificate
+ * @throws CertificateException
+ */
+ public static X509Certificate getCertificateFromXML(Element signedXML) throws CertificateException {
+
+ NodeList nList = signedXML.getElementsByTagNameNS(Constants.DSIG_NS_URI, "X509Certificate");
+
+ String base64CertString = XMLUtil.getFirstTextValueFromNodeList(nList);
+
+ if (StringUtils.isEmpty(base64CertString)) {
+ String msg = "XML does not contain a X509Certificate element.";
+ Logger.error(msg);
+ throw new CertificateException(msg);
+ }
+
+ InputStream is = new ByteArrayInputStream(Base64.decode(base64CertString));
+
+ X509Certificate cert;
+ try {
+ cert = new X509Certificate(is);
+ return cert;
+
+ } catch (Throwable e) {
+ throw new CertificateException(e);
+
+ } finally {
+ try {
+ is.close();
+
+ } catch (IOException e) {
+ Logger.warn("Close InputStream failed." , e);
+
+ }
+
+ }
+ }
+
+}