diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment')
2 files changed, 2349 insertions, 2012 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index 5ffff2787..a58f5fce2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -21,7 +21,6 @@ * that you distribute must include a readable copy of the "NOTICE" text file. */ - package at.gv.egovernment.moa.id.auth; import iaik.pki.PKIException; @@ -49,6 +48,7 @@ import org.apache.xpath.XPathAPI; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.AuthenticationException; @@ -114,2035 +114,2372 @@ import at.gv.egovernment.moa.util.DateTimeUtils; import at.gv.egovernment.moa.util.FileUtils; 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. + * 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$ + * @version $Id: AuthenticationServer.java 1273 2012-02-27 14:50:18Z kstranacher + * $ */ public class AuthenticationServer implements MOAIDAuthConstants { - /** single instance */ - private static AuthenticationServer instance; - /** session data store (session ID -> AuthenticationSession) */ - private static Map sessionStore = new HashMap(); - /** authentication data store (assertion handle -> AuthenticationData) */ - private static Map authenticationDataStore = new HashMap(); - /** - * time out in milliseconds used by {@link cleanup} for session store - */ - private long sessionTimeOut = 10 * 60 * 1000; // default 10 minutes - /** - * time out in milliseconds used by {@link cleanup} for authentication data store - */ - private long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes - - /** - * 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 request to select a BKU. - * <br/>Processing depends on value of {@link AuthConfigurationProvider#getBKUSelectionType}. - * <br/>For <code>bkuSelectionType==HTMLComplete</code>, a <code>returnURI</code> for the - * "BKU Auswahl" service is returned. - * <br/>For <code>bkuSelectionType==HTMLSelect</code>, an HTML form for BKU selection is returned. - * @param authURL base URL of MOA-ID Auth component - * @param target "Geschäftsbereich" - * @param oaURL online application URL requested - * @param bkuSelectionTemplateURL template for BKU selection form to be used - * in case of <code>HTMLSelect</code>; may be null - * @param templateURL URL providing an HTML template for the HTML form to be used - * for call <code>startAuthentication</code> - * @return for <code>bkuSelectionType==HTMLComplete</code>, the <code>returnURI</code> for the - * "BKU Auswahl" service; - * for <code>bkuSelectionType==HTMLSelect</code>, an HTML form for BKU selection - * @throws WrongParametersException upon missing parameters - * @throws AuthenticationException when the configured BKU selection service cannot be reached, - * and when the given bkuSelectionTemplateURL cannot be reached - * @throws ConfigurationException on missing configuration data - * @throws BuildException while building the HTML form - */ - public String selectBKU( - String authURL, - String target, - String oaURL, - String bkuSelectionTemplateURL, - String templateURL) - throws WrongParametersException, AuthenticationException, ConfigurationException, BuildException { - - //check if HTTP Connection may be allowed (through FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY) - String boolStr = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter( - AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); - if ((!authURL.startsWith("https:")) && (false == BoolUtils.valueOf(boolStr))) - throw new AuthenticationException("auth.07", new Object[] { authURL + "*" }); - if (isEmpty(authURL)) - throw new WrongParametersException("StartAuthentication", "AuthURL", "auth.05"); - if (isEmpty(oaURL)) - throw new WrongParametersException("StartAuthentication", PARAM_OA, "auth.05"); - - ConnectionParameter bkuConnParam = - AuthConfigurationProvider.getInstance().getBKUConnectionParameter(); - if (bkuConnParam == null) - throw new ConfigurationException( - "config.08", - new Object[] { "BKUSelection/ConnectionParameter" }); - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); - if (oaParam == null) - throw new AuthenticationException("auth.00", new Object[] { oaURL }); - - if (!oaParam.getBusinessService()) { - if (isEmpty(target)) - throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.05"); - } else { - if (!isEmpty(target)) { - Logger.info("Ignoring target parameter thus application type is \"businessService\""); - } - target = null; - } - - AuthenticationSession session = newSession(); - Logger.info("MOASession " + session.getSessionID() + " angelegt"); - session.setTarget(target); - session.setOAURLRequested(oaURL); - session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); - session.setAuthURL(authURL); - session.setTemplateURL(templateURL); - session.setBusinessService(oaParam.getBusinessService()); - String returnURL = - new DataURLBuilder().buildDataURL(authURL, REQ_START_AUTHENTICATION, session.getSessionID()); - String bkuSelectionType = AuthConfigurationProvider.getInstance().getBKUSelectionType(); - if (bkuSelectionType.equals(AuthConfigurationProvider.BKU_SELECTION_TYPE_HTMLCOMPLETE)) { - // bkuSelectionType==HTMLComplete - String redirectURL = bkuConnParam.getUrl() + "?" + AuthServlet.PARAM_RETURN + "=" + returnURL; - return redirectURL; - } else { - // bkuSelectionType==HTMLSelect - String bkuSelectTag; - try { - bkuSelectTag = readBKUSelectTag(AuthConfigurationProvider.getInstance(), bkuConnParam); - } catch (Throwable ex) { - throw new AuthenticationException( - "auth.11", - new Object[] { bkuConnParam.getUrl(), ex.toString()}, - ex); - } - String bkuSelectionTemplate = null; - // override template url by url from configuration file - if (oaParam.getBkuSelectionTemplateURL() != null) { - bkuSelectionTemplateURL = oaParam.getBkuSelectionTemplateURL(); - } - if (bkuSelectionTemplateURL != null) { - try { - bkuSelectionTemplate = new String(FileUtils.readURL(bkuSelectionTemplateURL)); - } catch (IOException ex) { - throw new AuthenticationException( - "auth.03", - new Object[] { bkuSelectionTemplateURL, ex.toString()}, - ex); - } - } - String htmlForm = - new SelectBKUFormBuilder().build(bkuSelectionTemplate, returnURL, bkuSelectTag); - return htmlForm; - } - } - /** - * Method readBKUSelectTag. - * @param conf the ConfigurationProvider - * @param connParam the ConnectionParameter for that connection - * @return String - * @throws ConfigurationException on config-errors - * @throws PKIException on PKI errors - * @throws IOException on any data error - * @throws GeneralSecurityException on security errors - */ - private String readBKUSelectTag(ConfigurationProvider conf, ConnectionParameter connParam) - throws ConfigurationException, PKIException, IOException, GeneralSecurityException { - - if (connParam.isHTTPSURL()) - return SSLUtils.readHttpsURL(conf, connParam); - else - return HTTPUtils.readHttpURL(connParam.getUrl()); - } - /** - * Processes the beginning of an authentication session. - * <ul> - * <li>Starts an authentication session</li> - * <li>Creates an <code><InfoboxReadRequest></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><InfoboxReadRequest></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ä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ü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 scheme determines the protocol used - * @param sourceID - * @return HTML form - * @throws AuthenticationException - * @see GetIdentityLinkFormBuilder - * @see InfoboxReadRequestBuilder - */ - public String startAuthentication( - String authURL, - String target, - String targetFriendlyName, - String oaURL, - String templateURL, - String bkuURL, - String useMandate, - String sessionID, - String scheme, - String sourceID) - throws WrongParametersException, AuthenticationException, ConfigurationException, BuildException { - - String useMandateString = null; - boolean useMandateBoolean = false; - if ((useMandate != null) && (useMandate.compareTo("") != 0)) { - useMandateString = useMandate; - } - else { - useMandateString = "false"; - } - - if (useMandateString.compareToIgnoreCase("true") == 0) - useMandateBoolean = true; - else - useMandateBoolean = false; - - if (isEmpty(sessionID)) { - if (isEmpty(authURL)) - throw new WrongParametersException("StartAuthentication", "AuthURL", "auth.05"); - - //check if HTTP Connection may be allowed (through FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY) - String boolStr = - AuthConfigurationProvider.getInstance().getGenericConfigurationParameter( - AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); - if ((!authURL.startsWith("https:")) && (false == BoolUtils.valueOf(boolStr))) - throw new AuthenticationException("auth.07", new Object[] { authURL + "*" }); - if (isEmpty(oaURL)) - throw new WrongParametersException("StartAuthentication", PARAM_OA, "auth.05"); - } - AuthenticationSession session; - OAAuthParameter oaParam; - if (sessionID != null) { - session = getSession(sessionID); - oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - } else { - oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); - if (oaParam == null) - throw new AuthenticationException("auth.00", new Object[] { oaURL }); - if (!oaParam.getBusinessService()) { - if (isEmpty(target)) - throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.05"); - } else { - if (useMandateBoolean) { - Logger.error("Online-Mandate Mode for bussines application not supported."); - throw new AuthenticationException("auth.17", null); - } - target = null; - targetFriendlyName = null; - } - session = newSession(); - Logger.info("MOASession " + session.getSessionID() + " angelegt"); - session.setTarget(target); - session.setTargetFriendlyName(targetFriendlyName); - session.setOAURLRequested(oaURL); - session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); - session.setAuthURL(authURL); - session.setTemplateURL(templateURL); - session.setBusinessService(oaParam.getBusinessService()); - if (sourceID != null) - session.setSourceID(sourceID); - } - // BKU URL has not been set yet, even if session already exists - if (bkuURL == null) { - if (scheme!=null && scheme.equalsIgnoreCase("https")) { - bkuURL = DEFAULT_BKU_HTTPS; - } else { - bkuURL = DEFAULT_BKU; - } - } - session.setBkuURL(bkuURL); - session.setDomainIdentifier(oaParam.getIdentityLinkDomainIdentifier()); - session.setUseMandate(useMandateString); - String infoboxReadRequest = - new InfoboxReadRequestBuilder().build(oaParam.getSlVersion12(), - oaParam.getBusinessService(), - oaParam.getIdentityLinkDomainIdentifier()); - - String dataURL = - new DataURLBuilder().buildDataURL( - session.getAuthURL(), - REQ_VERIFY_IDENTITY_LINK, - session.getSessionID()); - String template = null; - // override template url by url from configuration file - if (oaParam.getTemplateURL() != null) { - templateURL = oaParam.getTemplateURL(); - } else { - templateURL = session.getTemplateURL(); - } - if (templateURL != null) { - try { - template = new String(FileUtils.readURL(templateURL)); - } catch (IOException ex) { - throw new AuthenticationException( - "auth.03", - new Object[] { templateURL, ex.toString()}, - ex); - } - } - - - String pushInfobox = ""; - VerifyInfoboxParameters verifyInfoboxParameters = oaParam.getVerifyInfoboxParameters(); - if (verifyInfoboxParameters != null) { - pushInfobox = verifyInfoboxParameters.getPushInfobox(); - session.setPushInfobox(pushInfobox); - } - String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(oaParam.getSlVersion12()); - String certInfoDataURL = - new DataURLBuilder().buildDataURL( - session.getAuthURL(), - REQ_START_AUTHENTICATION, - session.getSessionID()); - String htmlForm = - new GetIdentityLinkFormBuilder().build( - template, - bkuURL, - infoboxReadRequest, - dataURL, - certInfoRequest, - certInfoDataURL, - pushInfobox); - return htmlForm; - } - /** - * Processes an <code><InfoboxReadResponse></code> sent by the - * security layer implementation.<br> - * <ul> - * <li>Validates given <code><InfoboxReadResponse></code></li> - * <li>Parses identity link enclosed in <code><InfoboxReadResponse></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><CreateXMLSignatureRequest></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><InfoboxReadResponse></code> - * @return String representation of the <code><CreateXMLSignatureRequest></code> - */ - public String verifyIdentityLink(String sessionID, Map infoboxReadResponseParameters) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ValidateException, - ServiceException { - - if (isEmpty(sessionID)) - throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_IDENTITY_LINK, PARAM_SESSIONID}); - - String xmlInfoboxReadResponse = (String)infoboxReadResponseParameters.get(PARAM_XMLRESPONSE); - - //System.out.println("PB: " + xmlInfoboxReadResponse); - - if (isEmpty(xmlInfoboxReadResponse)) - throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_IDENTITY_LINK, PARAM_XMLRESPONSE}); - - AuthenticationSession session = getSession(sessionID); - if (session.getTimestampIdentityLink() != null) - throw new AuthenticationException("auth.01", new Object[] { sessionID }); - session.setTimestampIdentityLink(); - AuthConfigurationProvider authConf = AuthConfigurationProvider.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 ausländische eID."); - return null; - } - // spezifikationsgemäßer (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 ausländische eID."); - return null; - } - - // for testing new identity link certificate -// xmlInfoboxReadResponse = null; -// try { -// File file = new File("c:/temp/XXXMuster.xml"); -// FileInputStream fis; -// -// fis = new FileInputStream(file); -// byte[] array = Utils.readFromInputStream(fis); -// -// xmlInfoboxReadResponse = new String(array); -// System.out.println(xmlInfoboxReadResponse); -// -// } catch (FileNotFoundException e) { -// e.printStackTrace(); -// } catch (UtilsException e) { -// e.printStackTrace(); -// } - - - - // 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()); - - // invokes the call - Element domVerifyXMLSignatureResponse = - new SignatureVerificationInvoker().verifyXMLSignature(domVerifyXMLSignatureRequest); - // parses the <VerifyXMLSignatureResponse> - VerifyXMLSignatureResponse verifyXMLSignatureResponse = - new VerifyXMLSignatureResponseParser(domVerifyXMLSignatureResponse).parseData(); - - if (identityLink.getIdentificationType().equalsIgnoreCase(Constants.URN_PREFIX_BASEID)) { - } - - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - - // if OA is type is business service the manifest validation result has to be ignored - boolean ignoreManifestValidationResult = oaParam.getBusinessService() ? true : false; - - // validates the <VerifyXMLSignatureResponse> - VerifyXMLSignatureResponseValidator.getInstance().validate( - verifyXMLSignatureResponse, - authConf.getIdentityLinkX509SubjectNames(), - VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, - ignoreManifestValidationResult); - - session.setIdentityLink(identityLink); - // now validate the extended infoboxes - verifyInfoboxes(session, infoboxReadResponseParameters, !oaParam.getProvideStammzahl()); - - return getCreateXMLSignatureRequestAuthBlockOrRedirect(session, authConf, oaParam); - } - - - /** - * 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><CreateXMLSignatureRequest></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><InfoboxReadResponse></code> - * @return String representation of the <code><CreateXMLSignatureRequest></code> - */ - public void verifyMandate(String sessionID, MISMandate mandate) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ValidateException, - ServiceException { - - if (isEmpty(sessionID)) - throw new AuthenticationException("auth.10", new Object[] { GET_MIS_SESSIONID, PARAM_SESSIONID}); - - String sMandate = new String(mandate.getMandate()); - if (sMandate == null | sMandate.compareToIgnoreCase("") == 0) { - Logger.error("Mandate is empty."); - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}); - } - - - AuthenticationSession session = getSession(sessionID); - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - - - - try { - // sets the extended SAML attributes for OID (Organwalter) - setExtendedSAMLAttributeForMandatesOID(session, mandate, oaParam.getBusinessService()); - } catch (SAXException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); - } catch (IOException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); - } catch (ParserConfigurationException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); - } catch (TransformerException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); + /** single instance */ + private static AuthenticationServer instance; + /** session data store (session ID -> AuthenticationSession) */ + private static Map sessionStore = new HashMap(); + /** authentication data store (assertion handle -> AuthenticationData) */ + private static Map authenticationDataStore = new HashMap(); + /** + * time out in milliseconds used by {@link cleanup} for session store + */ + private long sessionTimeOut = 10 * 60 * 1000; // default 10 minutes + /** + * time out in milliseconds used by {@link cleanup} for authentication data + * store + */ + private long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes + + /** + * 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 request to select a BKU. <br/> + * Processing depends on value of + * {@link AuthConfigurationProvider#getBKUSelectionType}. <br/> + * For <code>bkuSelectionType==HTMLComplete</code>, a <code>returnURI</code> + * for the "BKU Auswahl" service is returned. <br/> + * For <code>bkuSelectionType==HTMLSelect</code>, an HTML form for BKU + * selection is returned. + * + * @param authURL + * base URL of MOA-ID Auth component + * @param target + * "Geschäftsbereich" + * @param oaURL + * online application URL requested + * @param bkuSelectionTemplateURL + * template for BKU selection form to be used in case of + * <code>HTMLSelect</code>; may be null + * @param templateURL + * URL providing an HTML template for the HTML form to be used + * for call <code>startAuthentication</code> + * @return for <code>bkuSelectionType==HTMLComplete</code>, the + * <code>returnURI</code> for the "BKU Auswahl" service; for + * <code>bkuSelectionType==HTMLSelect</code>, an HTML form for BKU + * selection + * @throws WrongParametersException + * upon missing parameters + * @throws AuthenticationException + * when the configured BKU selection service cannot be reached, + * and when the given bkuSelectionTemplateURL cannot be reached + * @throws ConfigurationException + * on missing configuration data + * @throws BuildException + * while building the HTML form + */ + public String selectBKU(String authURL, String target, String oaURL, + String bkuSelectionTemplateURL, String templateURL) + throws WrongParametersException, AuthenticationException, + ConfigurationException, BuildException { + + // check if HTTP Connection may be allowed (through + // FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY) + String boolStr = AuthConfigurationProvider + .getInstance() + .getGenericConfigurationParameter( + AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); + if ((!authURL.startsWith("https:")) + && (false == BoolUtils.valueOf(boolStr))) + throw new AuthenticationException("auth.07", new Object[] { authURL + + "*" }); + if (isEmpty(authURL)) + throw new WrongParametersException("StartAuthentication", + "AuthURL", "auth.05"); + if (isEmpty(oaURL)) + throw new WrongParametersException("StartAuthentication", PARAM_OA, + "auth.05"); + + ConnectionParameter bkuConnParam = AuthConfigurationProvider + .getInstance().getBKUConnectionParameter(); + if (bkuConnParam == null) + throw new ConfigurationException("config.08", + new Object[] { "BKUSelection/ConnectionParameter" }); + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(oaURL); + if (oaParam == null) + throw new AuthenticationException("auth.00", new Object[] { oaURL }); + + if (!oaParam.getBusinessService()) { + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", + PARAM_TARGET, "auth.05"); + } else { + if (!isEmpty(target)) { + Logger + .info("Ignoring target parameter thus application type is \"businessService\""); + } + target = null; + } + + AuthenticationSession session = newSession(); + Logger.info("MOASession " + session.getSessionID() + " angelegt"); + session.setTarget(target); + session.setOAURLRequested(oaURL); + session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); + session.setAuthURL(authURL); + session.setTemplateURL(templateURL); + session.setBusinessService(oaParam.getBusinessService()); + String returnURL = new DataURLBuilder().buildDataURL(authURL, + REQ_START_AUTHENTICATION, session.getSessionID()); + String bkuSelectionType = AuthConfigurationProvider.getInstance() + .getBKUSelectionType(); + if (bkuSelectionType + .equals(AuthConfigurationProvider.BKU_SELECTION_TYPE_HTMLCOMPLETE)) { + // bkuSelectionType==HTMLComplete + String redirectURL = bkuConnParam.getUrl() + "?" + + AuthServlet.PARAM_RETURN + "=" + returnURL; + return redirectURL; + } else { + // bkuSelectionType==HTMLSelect + String bkuSelectTag; + try { + bkuSelectTag = readBKUSelectTag(AuthConfigurationProvider + .getInstance(), bkuConnParam); + } catch (Throwable ex) { + throw new AuthenticationException("auth.11", new Object[] { + bkuConnParam.getUrl(), ex.toString() }, ex); + } + String bkuSelectionTemplate = null; + // override template url by url from configuration file + if (oaParam.getBkuSelectionTemplateURL() != null) { + bkuSelectionTemplateURL = oaParam.getBkuSelectionTemplateURL(); + } + if (bkuSelectionTemplateURL != null) { + try { + bkuSelectionTemplate = new String(FileUtils + .readURL(bkuSelectionTemplateURL)); + } catch (IOException ex) { + throw new AuthenticationException("auth.03", new Object[] { + bkuSelectionTemplateURL, ex.toString() }, ex); + } + } + String htmlForm = new SelectBKUFormBuilder().build( + bkuSelectionTemplate, returnURL, bkuSelectTag); + return htmlForm; + } + } + + /** + * Method readBKUSelectTag. + * + * @param conf + * the ConfigurationProvider + * @param connParam + * the ConnectionParameter for that connection + * @return String + * @throws ConfigurationException + * on config-errors + * @throws PKIException + * on PKI errors + * @throws IOException + * on any data error + * @throws GeneralSecurityException + * on security errors + */ + private String readBKUSelectTag(ConfigurationProvider conf, + ConnectionParameter connParam) throws ConfigurationException, + PKIException, IOException, GeneralSecurityException { + + if (connParam.isHTTPSURL()) + return SSLUtils.readHttpsURL(conf, connParam); + else + return HTTPUtils.readHttpURL(connParam.getUrl()); } - - - if (oaParam.getProvideFullMandatorData()) { + + /** + * Processes the beginning of an authentication session. + * <ul> + * <li>Starts an authentication session</li> + * <li>Creates an <code><InfoboxReadRequest></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><InfoboxReadRequest></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ä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ü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 scheme + * determines the protocol used + * @param sourceID + * @return HTML form + * @throws AuthenticationException + * @see GetIdentityLinkFormBuilder + * @see InfoboxReadRequestBuilder + */ + public String startAuthentication(String authURL, String target, + String targetFriendlyName, String oaURL, String templateURL, + String bkuURL, String useMandate, String sessionID, String scheme, + String sourceID) throws WrongParametersException, + AuthenticationException, ConfigurationException, BuildException { + + String useMandateString = null; + boolean useMandateBoolean = false; + if ((useMandate != null) && (useMandate.compareTo("") != 0)) { + useMandateString = useMandate; + } else { + useMandateString = "false"; + } + + if (useMandateString.compareToIgnoreCase("true") == 0) + useMandateBoolean = true; + else + useMandateBoolean = false; + + if (isEmpty(sessionID)) { + if (isEmpty(authURL)) + throw new WrongParametersException("StartAuthentication", + "AuthURL", "auth.05"); + + // check if HTTP Connection may be allowed (through + // FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY) + String boolStr = AuthConfigurationProvider + .getInstance() + .getGenericConfigurationParameter( + AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); + if ((!authURL.startsWith("https:")) + && (false == BoolUtils.valueOf(boolStr))) + throw new AuthenticationException("auth.07", + new Object[] { authURL + "*" }); + if (isEmpty(oaURL)) + throw new WrongParametersException("StartAuthentication", + PARAM_OA, "auth.05"); + } + AuthenticationSession session; + OAAuthParameter oaParam; + if (sessionID != null) { + session = getSession(sessionID); + oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + } else { + oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(oaURL); + if (oaParam == null) + throw new AuthenticationException("auth.00", + new Object[] { oaURL }); + if (!oaParam.getBusinessService()) { + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", + PARAM_TARGET, "auth.05"); + } else { + if (useMandateBoolean) { + Logger + .error("Online-Mandate Mode for bussines application not supported."); + throw new AuthenticationException("auth.17", null); + } + target = null; + targetFriendlyName = null; + } + session = newSession(); + Logger.info("MOASession " + session.getSessionID() + " angelegt"); + session.setTarget(target); + session.setTargetFriendlyName(targetFriendlyName); + session.setOAURLRequested(oaURL); + session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); + session.setAuthURL(authURL); + session.setTemplateURL(templateURL); + session.setBusinessService(oaParam.getBusinessService()); + if (sourceID != null) + session.setSourceID(sourceID); + } + // BKU URL has not been set yet, even if session already exists + if (bkuURL == null) { + if (scheme != null && scheme.equalsIgnoreCase("https")) { + bkuURL = DEFAULT_BKU_HTTPS; + } else { + bkuURL = DEFAULT_BKU; + } + } + session.setBkuURL(bkuURL); + session.setDomainIdentifier(oaParam.getIdentityLinkDomainIdentifier()); + session.setUseMandate(useMandateString); + String infoboxReadRequest = new InfoboxReadRequestBuilder().build( + oaParam.getSlVersion12(), oaParam.getBusinessService(), oaParam + .getIdentityLinkDomainIdentifier()); + + String dataURL = new DataURLBuilder().buildDataURL( + session.getAuthURL(), REQ_VERIFY_IDENTITY_LINK, session + .getSessionID()); + String template = null; + // override template url by url from configuration file + if (oaParam.getTemplateURL() != null) { + templateURL = oaParam.getTemplateURL(); + } else { + templateURL = session.getTemplateURL(); + } + if (templateURL != null) { + try { + template = new String(FileUtils.readURL(templateURL)); + } catch (IOException ex) { + throw new AuthenticationException("auth.03", new Object[] { + templateURL, ex.toString() }, ex); + } + } + + String pushInfobox = ""; + VerifyInfoboxParameters verifyInfoboxParameters = oaParam + .getVerifyInfoboxParameters(); + if (verifyInfoboxParameters != null) { + pushInfobox = verifyInfoboxParameters.getPushInfobox(); + session.setPushInfobox(pushInfobox); + } + String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder() + .build(oaParam.getSlVersion12()); + String certInfoDataURL = new DataURLBuilder() + .buildDataURL(session.getAuthURL(), REQ_START_AUTHENTICATION, + session.getSessionID()); + String htmlForm = new GetIdentityLinkFormBuilder().build(template, + bkuURL, infoboxReadRequest, dataURL, certInfoRequest, + certInfoDataURL, pushInfobox); + return htmlForm; + } + + /** + * Processes an <code><InfoboxReadResponse></code> sent by the + * security layer implementation.<br> + * <ul> + * <li>Validates given <code><InfoboxReadResponse></code></li> + * <li>Parses identity link enclosed in + * <code><InfoboxReadResponse></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><CreateXMLSignatureRequest></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><InfoboxReadResponse></code> + * @return String representation of the + * <code><CreateXMLSignatureRequest></code> + */ + public String verifyIdentityLink(String sessionID, + Map infoboxReadResponseParameters) throws AuthenticationException, + BuildException, ParseException, ConfigurationException, + ValidateException, ServiceException { + + if (isEmpty(sessionID)) + throw new AuthenticationException("auth.10", new Object[] { + REQ_VERIFY_IDENTITY_LINK, PARAM_SESSIONID }); + + String xmlInfoboxReadResponse = (String) infoboxReadResponseParameters + .get(PARAM_XMLRESPONSE); + + // System.out.println("PB: " + xmlInfoboxReadResponse); + + if (isEmpty(xmlInfoboxReadResponse)) + throw new AuthenticationException("auth.10", new Object[] { + REQ_VERIFY_IDENTITY_LINK, PARAM_XMLRESPONSE }); + + AuthenticationSession session = getSession(sessionID); + if (session.getTimestampIdentityLink() != null) + throw new AuthenticationException("auth.01", + new Object[] { sessionID }); + session.setTimestampIdentityLink(); + AuthConfigurationProvider authConf = AuthConfigurationProvider + .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 ausländische eID."); + return null; + } + // spezifikationsgemäßer (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 ausländische eID."); + return null; + } + + // for testing new identity link certificate + // xmlInfoboxReadResponse = null; + // try { + // File file = new File("c:/temp/XXXMuster.xml"); + // FileInputStream fis; + // + // fis = new FileInputStream(file); + // byte[] array = Utils.readFromInputStream(fis); + // + // xmlInfoboxReadResponse = new String(array); + // System.out.println(xmlInfoboxReadResponse); + // + // } catch (FileNotFoundException e) { + // e.printStackTrace(); + // } catch (UtilsException e) { + // e.printStackTrace(); + // } + + // 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()); + + // invokes the call + Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker() + .verifyXMLSignature(domVerifyXMLSignatureRequest); + // parses the <VerifyXMLSignatureResponse> + VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( + domVerifyXMLSignatureResponse).parseData(); + + if (identityLink.getIdentificationType().equalsIgnoreCase( + Constants.URN_PREFIX_BASEID)) { + } + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + + // if OA is type is business service the manifest validation result has + // to be ignored + boolean ignoreManifestValidationResult = oaParam.getBusinessService() ? true + : false; + + // validates the <VerifyXMLSignatureResponse> + VerifyXMLSignatureResponseValidator.getInstance().validate( + verifyXMLSignatureResponse, + authConf.getIdentityLinkX509SubjectNames(), + VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, + ignoreManifestValidationResult); + + session.setIdentityLink(identityLink); + // now validate the extended infoboxes + verifyInfoboxes(session, infoboxReadResponseParameters, !oaParam + .getProvideStammzahl()); + + return getCreateXMLSignatureRequestAuthBlockOrRedirect(session, + authConf, oaParam); + } + + /** + * 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><CreateXMLSignatureRequest></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><InfoboxReadResponse></code> + * @return String representation of the + * <code><CreateXMLSignatureRequest></code> + */ + public void verifyMandate(String sessionID, MISMandate mandate) + throws AuthenticationException, BuildException, ParseException, + ConfigurationException, ValidateException, ServiceException { + + if (isEmpty(sessionID)) + throw new AuthenticationException("auth.10", new Object[] { + GET_MIS_SESSIONID, PARAM_SESSIONID }); + + String sMandate = new String(mandate.getMandate()); + if (sMandate == null | sMandate.compareToIgnoreCase("") == 0) { + Logger.error("Mandate is empty."); + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }); + } + + AuthenticationSession session = getSession(sessionID); + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + try { - // set extended SAML attributes if provideMandatorData is true - setExtendedSAMLAttributeForMandates(session, mandate, oaParam.getBusinessService(), oaParam.getProvideStammzahl()); + // sets the extended SAML attributes for OID (Organwalter) + setExtendedSAMLAttributeForMandatesOID(session, mandate, oaParam + .getBusinessService()); } catch (SAXException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); } catch (IOException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); } catch (ParserConfigurationException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); } catch (TransformerException e) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}, e); + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); } - } - - } - - /** - * - * @param session - * @param authConf - * @param oaParam - * @return - * @throws ConfigurationException - * @throws BuildException - * @throws ValidateException - */ - public String getCreateXMLSignatureRequestAuthBlockOrRedirect(AuthenticationSession session, AuthConfigurationProvider 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 = AuthConfigurationProvider.getInstance(); - if (oaParam==null) oaParam = AuthConfigurationProvider.getInstance(). - getOnlineApplicationParameter(session.getPublicOAURLPrefix()); - -// if (!fromMandate) { - //BZ.., calculate bPK for signing to be already present in AuthBlock - IdentityLink identityLink = session.getIdentityLink(); - if (identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { - // only compute bPK if online application is a public service and we have the Stammzahl - String bpkBase64 = new BPKBuilder().buildBPK( - identityLink.getIdentificationValue(), - session.getTarget()); - identityLink.setIdentificationValue(bpkBase64); - } - //..BZ -// } - - - // builds the AUTH-block - String authBlock = buildAuthenticationBlock(session, oaParam); - -// session.setAuthBlock(authBlock); - // builds the <CreateXMLSignatureRequest> - String[] transformsInfos = oaParam.getTransformsInfos(); - if ((transformsInfos == null) || (transformsInfos.length == 0)) { - // no OA specific transforms specified, use default ones - transformsInfos = authConf.getTransformsInfos(); - } - String createXMLSignatureRequest = - new CreateXMLSignatureRequestBuilder().build(authBlock, - oaParam.getKeyBoxIdentifier(), - transformsInfos, - oaParam.getSlVersion12()); - 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><CreateXMLSignatureRequest></code> - */ - public String createXMLSignatureRequestForeignID(String sessionID, X509Certificate cert) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ValidateException, - ServiceException { - - if (isEmpty(sessionID)) - throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID}); - - AuthenticationSession session = getSession(sessionID); - - AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); - - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - - return getCreateXMLSignatureRequestForeigID(session, authConf, oaParam, cert); - } - - public String getCreateXMLSignatureRequestForeigID(AuthenticationSession session, AuthConfigurationProvider 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 = AuthConfigurationProvider.getInstance(); - if (oaParam==null) oaParam = AuthConfigurationProvider.getInstance(). - getOnlineApplicationParameter(session.getPublicOAURLPrefix()); - - Principal subject = cert.getSubjectDN(); - - String createXMLSignatureRequest = - new CreateXMLSignatureRequestBuilder().buildForeignID(subject.toString(), oaParam, session); - return createXMLSignatureRequest; -} - - /** - * Processes an <code><CreateXMLSignatureResponse></code> sent by the - * security layer implementation.<br> - * <ul> - * <li>Validates given <code><CreateXMLSignatureResponse></code></li> - * <li>Parses response enclosed in <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> - */ - public X509Certificate verifyXMLSignature(String sessionID, Map createXMLSignatureResponseParameters) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ValidateException, - ServiceException { - - - 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}); - - AuthenticationSession session = getSession(sessionID); - /*if (session.getTimestampIdentityLink() != null) - throw new AuthenticationException("auth.01", new Object[] { sessionID });*/ - //session.setTimestampIdentityLink(); - AuthConfigurationProvider authConf = AuthConfigurationProvider.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(); - - - //int code = verifyXMLSignatureResponse.getSignatureCheckCode(); - - return verifyXMLSignatureResponse.getX509certificate(); - - } - - /** - * Processes an <code><CreateXMLSignatureResponse></code> sent by the - * security layer implementation.<br> - * <ul> - * <li>Validates given <code><CreateXMLSignatureResponse></code></li> - * <li>Parses response enclosed in <code><CreateXMLSignatureResponse></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 readInfoboxResponseParameters The parameters from the response returned from - * the BKU including the <code><ReadInfoboxResponse></code> - */ - public X509Certificate getCertificate(String sessionID, Map readInfoboxResponseParameters) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ValidateException, - ServiceException { - - - 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(); - - return cert; - - } - - /** - * Builds an authentication block <code><saml:Assertion></code> from given session data. - * @param session authentication session - * - * @return <code><saml:Assertion></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 = identityLink.getIdentificationValue(); - String identificationType = identityLink.getIdentificationType(); - - String issueInstant = DateTimeUtils.buildDateTime(Calendar.getInstance(), oaParam.getUseUTC()); - 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(); - String oaURL = session.getPublicOAURLPrefix().replaceAll("&", "&"); - List extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); - String authBlock = new AuthenticationBlockAssertionBuilder().buildAuthBlock( - issuer, - issueInstant, - authURL, - target, - targetFriendlyName, - identificationValue, - identificationType, - oaURL, - gebDat, - extendedSAMLAttributes, - session); - - 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 infoboxReadResponseParams The parameters returned from the BKU as response - * to an infobox read request (including the infobox - * tokens to be verified). - * @param hideStammzahl Indicates whether source pins (<code>Stammzahl</code>en) - * should be hidden in any SAML attribute that may be - * returned by a validator. - * - * @throws AuthenticationException If the verification of at least one infobox fails. - * @throws ConfigurationException If the OAuthParameter cannot be extracted. - */ - private void verifyInfoboxes( - AuthenticationSession session, Map infoboxReadResponseParams, boolean hideStammzahl) - throws ValidateException, ConfigurationException - { - - AuthConfigurationProvider authConfigurationProvider = AuthConfigurationProvider.getInstance(); - // get the default VerifyInfobox parameters - Map defaultInfoboxParameters = null; - VerifyInfoboxParameters defaultVerifyInfoboxParameters = - authConfigurationProvider.getDefaultVerifyInfoboxParameters(); - if (defaultVerifyInfoboxParameters != null) { - defaultInfoboxParameters = defaultVerifyInfoboxParameters.getInfoboxParameters(); - } - // get the OA specific VerifyInfobox parameters - Map infoboxParameters = null; - OAAuthParameter oaParam = - authConfigurationProvider.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); - VerifyInfoboxParameters verifyInfoboxParameters = oaParam.getVerifyInfoboxParameters(); - session.setExtendedSAMLAttributesAUTH(new Vector()); // Initialize SAML Attributes - session.setExtendedSAMLAttributesOA(new Vector()); - - //System.out.println("SAML set: " + session.getExtendedSAMLAttributesAUTH().size()); - - if (verifyInfoboxParameters != null) { - - infoboxParameters = verifyInfoboxParameters.getInfoboxParameters(); - // get the list of infobox identifiers - List identifiers = verifyInfoboxParameters.getIdentifiers(); - if (identifiers != null) { - // step through the identifiers and verify the infoboxes - Iterator it = identifiers.iterator(); - while (it.hasNext()) { - String identifier = (String)it.next(); - // get the infobox read response from the map of parameters - String infoboxReadResponse = (String)infoboxReadResponseParams.get(identifier); - // get the configuration parameters - VerifyInfoboxParameter verifyInfoboxParameter = null; - Object object = infoboxParameters.get(identifier); - // if not present, use default - if ((object == null) && (defaultInfoboxParameters != null)) { - object = defaultInfoboxParameters.get(identifier); - } - if (object != null) { - verifyInfoboxParameter = (VerifyInfoboxParameter)object; - } - if (infoboxReadResponse != null) { - if (verifyInfoboxParameter == null) { - // should not happen because of the pushinfobox mechanism; check it anyway - Logger.error("No validator for verifying \"" + identifier + "\"-infobox configured."); - throw new ValidateException("validator.41", new Object[] {identifier}); - } else { - String friendlyName = verifyInfoboxParameter.getFriendlyName(); - boolean isParepRequest = false; - - // parse the infobox read reponse - List infoboxTokenList = null; - try { - infoboxTokenList = - ExtendedInfoboxReadResponseParser.parseInfoboxReadResponse(infoboxReadResponse, friendlyName); - } catch (ParseException e) { - Logger.error("InfoboxReadResponse for \"" + identifier + - "\"-infobox could not be parsed successfully: " + e.getMessage()); - throw new ValidateException("validator.43", new Object[] {friendlyName}); - } - // set compatibility mode for mandates infobox and all infoboxes (it is possible to be a parep infobox) - //session.setMandateCompatibilityMode(ParepConfiguration.isMandateCompatibilityMode(verifyInfoboxParameter.getApplicationSpecificParams())); - // check for party representation in mandates infobox - if (Constants.INFOBOXIDENTIFIER_MANDATES.equalsIgnoreCase(identifier) && !((infoboxTokenList == null || infoboxTokenList.size() == 0))){ - //We need app specific parameters - if (null==verifyInfoboxParameter.getApplicationSpecificParams()) { - throw new ValidateException("validator.66", new Object[] {friendlyName}); - } - Element mandate = ParepValidator.extractPrimaryToken(infoboxTokenList); - //ParepUtils.serializeElement(mandate, System.out); - String mandateID = ParepUtils.extractRepresentativeID(mandate); - if (!isEmpty(mandateID) && - ("*".equals(mandateID) || mandateID.startsWith(MOAIDAuthConstants.PARTY_REPRESENTATION_OID_NUMBER))) { - isParepRequest = true; - } - if (!isParepRequest) { - //if mandates validator is disabled we must throw an error in this case - if (!ParepUtils.isValidatorEnabled(verifyInfoboxParameter.getApplicationSpecificParams())) { - throw new ValidateException("validator.60", new Object[] {friendlyName}); - } - } - } - - // get the class for validating the infobox - InfoboxValidator infoboxValidator = null; - try { - Class validatorClass = null; - if (isParepRequest) { - // Mandates infobox in party representation mode - validatorClass = Class.forName("at.gv.egovernment.moa.id.auth.validator.parep.ParepValidator"); - } else { - validatorClass = Class.forName(verifyInfoboxParameter.getValidatorClassName()); - } - infoboxValidator = (InfoboxValidator) validatorClass.newInstance(); - } catch (Exception e) { - Logger.error("Could not load validator class \"" + verifyInfoboxParameter.getValidatorClassName() + - "\" for \"" + identifier + "\"-infobox: " + e.getMessage()); - throw new ValidateException("validator.42", new Object[] {friendlyName}); - } - Logger.debug("Successfully loaded validator class \"" + verifyInfoboxParameter.getValidatorClassName() + - "\" for \"" + identifier + "\"-infobox."); - // build the parameters for validating the infobox - InfoboxValidatorParams infoboxValidatorParams = - InfoboxValidatorParamsBuilder.buildInfoboxValidatorParams( - session, verifyInfoboxParameter, infoboxTokenList, oaParam); - - // now validate the infobox - InfoboxValidationResult infoboxValidationResult = null; - try { - infoboxValidationResult = infoboxValidator.validate(infoboxValidatorParams); - } catch (ValidateException e) { - Logger.error("Error validating " + identifier + " infobox:" + e.getMessage()); - throw new ValidateException( - "validator.44", new Object[] {friendlyName}); - } - if (!infoboxValidationResult.isValid()) { - Logger.info("Validation of " + identifier + " infobox failed."); - throw new ValidateException( - "validator.40", new Object[] {friendlyName, infoboxValidationResult.getErrorMessage()}); - } - - Logger.info(identifier + " infobox successfully validated."); - // store the validator for post processing - session.addInfoboxValidator(identifier, friendlyName, infoboxValidator); - - // get the SAML attributes to be appended to the AUTHBlock or to the final - // SAML Assertion - AddAdditionalSAMLAttributes(session, infoboxValidationResult.getExtendedSamlAttributes(), identifier, friendlyName); - } - } else { - if ((verifyInfoboxParameter !=null) && (verifyInfoboxParameter.isRequired())) { - Logger.info("Infobox \"" + identifier + "\" is required, but not returned from the BKU"); - throw new ValidateException( - "validator.48", new Object[] {verifyInfoboxParameter.getFriendlyName()}); - } - Logger.debug("Infobox \"" + identifier + "\" not returned from BKU."); - } - } - } - } - } - - /** - * 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 setExtendedSAMLAttributeForMandates( - AuthenticationSession session, MISMandate mandate, boolean business, boolean provideStammzahl) - throws ValidateException, ConfigurationException, SAXException, IOException, ParserConfigurationException, TransformerException - { - - ExtendedSAMLAttribute[] extendedSamlAttributes = addExtendedSamlAttributes(mandate, business, provideStammzahl); - - - AddAdditionalSAMLAttributes(session, extendedSamlAttributes, "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"); - - } - - /** - * Intermediate processing of the infoboxes. The first pending infobox - * validator may validate the provided input - * - * @param session The current authentication session - * @param parameters The parameters got returned by the user input fields - */ - public static void processInput(AuthenticationSession session, Map parameters) throws ValidateException - { - - // post processing of the infoboxes - Iterator iter = session.getInfoboxValidatorIterator(); - if (iter != null) { - while (iter.hasNext()) { - Vector infoboxValidatorVector = (Vector) iter.next(); - InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector.get(2); - if (!ParepUtils.isEmpty(infoboxvalidator.getForm())) { - String identifier = (String) infoboxValidatorVector.get(0); - String friendlyName = (String) infoboxValidatorVector.get(1); - InfoboxValidationResult infoboxValidationResult = null; - try { - infoboxValidationResult = infoboxvalidator.validate(parameters); - } catch (ValidateException e) { - Logger.error("Error validating " + identifier + " infobox:" + e.getMessage()); - throw new ValidateException( - "validator.44", new Object[] {friendlyName}); - } - if (!infoboxValidationResult.isValid()) { - Logger.info("Validation of " + identifier + " infobox failed."); - throw new ValidateException( - "validator.40", new Object[] {friendlyName, infoboxValidationResult.getErrorMessage()}); - } - AddAdditionalSAMLAttributes(session, infoboxValidationResult.getExtendedSamlAttributes(), identifier, friendlyName); - } - } - } - } - - /** - * 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 oaAttributes = session.getExtendedSAMLAttributesOA(); - if (oaAttributes==null) oaAttributes = new Vector(); - List authAttributes = session.getExtendedSAMLAttributesAUTH(); - if (authAttributes==null) authAttributes = new Vector(); - 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 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, MISMandate mandate) throws ValidateException -// { -// -// List oaAttributes = session.getExtendedSAMLAttributesOA(); -// if (oaAttributes==null) oaAttributes = new Vector(); -// List authAttributes = session.getExtendedSAMLAttributesAUTH(); -// if (authAttributes==null) authAttributes = new Vector(); -// -// -// addExtendedSamlAttributes(authAttributes, mandate); -// -// 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 - */ - - private static ExtendedSAMLAttribute[] addExtendedSamlAttributes(MISMandate mandate, boolean business, boolean provideStammzahl) throws SAXException, IOException, ParserConfigurationException, TransformerException { - Vector extendedSamlAttributes = new Vector(); - - - extendedSamlAttributes.clear(); - - //extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_RAW, mandate, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); - - // 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); - - // first check if physical person - //Element name = (Element) XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Name/pr:GivenName", nameSpaceNode); - //String mandatorname = ParepUtils.extractMandatorName(mandator); - - //extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_NAME, mandatorname, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); - // Geburtsdatum - //String dob = ParepUtils.extractMandatorDateOfBirth(mandator); - //if (dob != null && !"".equals(dob)) { - // extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_DOB, dob, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); - //} - - // Mandate - extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.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(ParepValidator.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(ParepValidator.EXT_SAML_MANDATE_WBPK, wbpk, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); - } - } - -// String oid = mandate.getProfRep(); -// if (oid != null) { -// String oidDescription = mandate.getTextualDescriptionOfOID(); -// extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_OIDTEXTUALDESCRIPTION, oidDescription, 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 extendedSamlAttributes = new Vector(); - - - extendedSamlAttributes.clear(); - - // RepresentationType - extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_REPRESENTATIONTYPE, ParepValidator.EXT_SAML_MANDATE_REPRESENTATIONTEXT, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); - - - String oid = mandate.getProfRep(); - - if (oid != null) { - extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_OID, oid, SZRGWConstants.MANDATE_NS, ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); - String oidDescription = mandate.getTextualDescriptionOfOID(); - extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl(ParepValidator.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); - return doc.getDocumentElement(); - } - private static void replaceExtendedSAMLAttribute(List attributes, ExtendedSAMLAttribute samlAttribute) { - if (null==attributes) { - attributes = new Vector(); - } 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><CreateXMLSignatureResponse></code> sent by the - * security layer implementation.<br> - * <ul> - * <li>Validates given <code><CreateXMLSignatureResponse></code></li> - * <li>Parses <code><CreateXMLSignatureResponse></code> for error codes</li> - * <li>Parses authentication block enclosed in - * <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> - * @return SAML artifact needed for retrieving authentication data, encoded BASE64 - */ - public String verifyAuthenticationBlock( - String sessionID, - String xmlCreateXMLSignatureReadResponse) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ServiceException, - ValidateException { - - if (isEmpty(sessionID)) - 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}); - AuthenticationSession session = getSession(sessionID); - AuthConfigurationProvider authConf = AuthConfigurationProvider.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> - new CreateXMLSignatureResponseValidator().validate(csresp, session); - // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call - String[] vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); - String tpid = authConf.getMoaSpAuthBlockTrustProfileID(); - Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp, vtids, tpid); - // debug output - - // invokes the call - Element domVsresp = new SignatureVerificationInvoker().verifyXMLSignature(domVsreq); - // debug output - - // 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())); - } - } - } - - // validates the <VerifyXMLSignatureResponse> - VerifyXMLSignatureResponseValidator.getInstance().validate( - vsresp, - null, - VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, - false); - - - // TODO See Bug #144 - // Compare AuthBlock Data with information stored in session, especially date and time - - - // compares the public keys from the identityLink with the AuthBlock - VerifyXMLSignatureResponseValidator.getInstance().validateCertificate( - vsresp, - session.getIdentityLink()); - - // post processing of the infoboxes - Iterator iter = session.getInfoboxValidatorIterator(); - boolean formpending = false; - if (iter != null) { - while (!formpending && iter.hasNext()) { - Vector infoboxValidatorVector = (Vector) iter.next(); - String identifier = (String) infoboxValidatorVector.get(0); - String friendlyName = (String) infoboxValidatorVector.get(1); - InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector.get(2); - InfoboxValidationResult infoboxValidationResult = null; - try { - infoboxValidationResult = infoboxvalidator.validate(csresp.getSamlAssertion()); - } catch (ValidateException e) { - Logger.error("Error validating " + identifier + " infobox:" + e.getMessage()); - throw new ValidateException( - "validator.44", new Object[] {friendlyName}); - } - if (!infoboxValidationResult.isValid()) { - Logger.info("Validation of " + identifier + " infobox failed."); - throw new ValidateException( - "validator.40", new Object[] {friendlyName, infoboxValidationResult.getErrorMessage()}); - } - String form = infoboxvalidator.getForm(); - if (ParepUtils.isEmpty(form)) { - AddAdditionalSAMLAttributes(session, infoboxValidationResult.getExtendedSamlAttributes(), identifier, friendlyName); - } else { - return "Redirect to Input Processor"; - } - } - } - - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - boolean useUTC = oaParam.getUseUTC(); - boolean useCondition = oaParam.getUseCondition(); - int conditionLength = oaParam.getConditionLength(); - - // builds authentication data and stores it together with a SAML artifact - AuthenticationData authData = buildAuthenticationData(session, vsresp, useUTC); - - if (session.getUseMandate()) { - // mandate mode - //session.setAssertionAuthBlock(assertionAuthBlock) - - // set signer certificate - session.setSignerCertificate(vsresp.getX509certificate()); - - return null; - } - else { - - String samlAssertion = - new AuthenticationDataAssertionBuilder().build( - authData, - session.getAssertionPrPerson(), - session.getAssertionAuthBlock(), - session.getAssertionIlAssertion(), - session.getBkuURL(), - session.getAssertionSignerCertificateBase64(), - session.getAssertionBusinessService(), - session.getExtendedSAMLAttributesOA(), - useCondition, - conditionLength); - authData.setSamlAssertion(samlAssertion); - - String assertionFile = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter("AuthenticationServer.WriteAssertionToFile"); - if (!ParepUtils.isEmpty(assertionFile)) + + if (oaParam.getProvideFullMandatorData()) { try { - ParepUtils.saveStringToFile(samlAssertion, new File(assertionFile)); + // set extended SAML attributes if provideMandatorData is true + setExtendedSAMLAttributeForMandates(session, mandate, oaParam + .getBusinessService(), oaParam.getProvideStammzahl()); + } catch (SAXException e) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); } catch (IOException e) { - throw new BuildException( - "builder.00", - new Object[] { "AuthenticationData", e.toString()}, - e); - } - - String samlArtifact = - new SAMLArtifactBuilder().build(session.getAuthURL(), session.getSessionID(), session.getSourceID()); - storeAuthenticationData(samlArtifact, authData); - - // invalidates the authentication session - sessionStore.remove(sessionID); - Logger.info( - "Anmeldedaten zu MOASession " + sessionID + " angelegt, SAML Artifakt " + samlArtifact); - return samlArtifact; - - } - - - - - } - - /** - * Processes a <code><CreateXMLSignatureResponse></code> sent by the - * security layer implementation.<br> - * <ul> - * <li>Validates given <code><CreateXMLSignatureResponse></code></li> - * <li>Parses <code><CreateXMLSignatureResponse></code> for error codes</li> - * <li>Parses authentication block enclosed in - * <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> - * @return SAML artifact needed for retrieving authentication data, encoded BASE64 - */ - public String verifyAuthenticationBlockMandate( - String sessionID, - Element mandate) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ServiceException, - ValidateException { - - if (isEmpty(sessionID)) - throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID}); - AuthenticationSession session = getSession(sessionID); - //AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); - - - IdentityLink tempIdentityLink = null; - - if (session.getUseMandate()) { - tempIdentityLink = new IdentityLink(); - Element mandator = ParepUtils.extractMandator(mandate); - String dateOfBirth = ""; - Element prPerson = null; - String familyName = ""; - String givenName = ""; - String identificationType = ""; - String identificationValue = ""; - if (mandator != null) { - boolean physical = ParepUtils.isPhysicalPerson(mandator); - if (physical) { - familyName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:FamilyName/text()"); - givenName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:GivenName/text()"); - dateOfBirth = ParepUtils.extractMandatorDateOfBirth(mandator); - } else { - familyName = ParepUtils.extractMandatorFullName(mandator); - } - identificationType = ParepUtils.getIdentification(mandator, "Type"); - identificationValue = ParepUtils.extractMandatorWbpk(mandator); - prPerson = ParepUtils.extractPrPersonOfMandate(mandate); - if (physical && session.getBusinessService() && identificationType!=null && Constants.URN_PREFIX_BASEID.equals(identificationType)) { - // now we calculate the wbPK and do so if we got it from the BKU - identificationType = Constants.URN_PREFIX_WBPK + "+" + session.getDomainIdentifier(); - identificationValue = new BPKBuilder().buildWBPK(identificationValue, session.getDomainIdentifier()); - ParepUtils.HideStammZahlen(prPerson, true, null, null, true); - } - - - tempIdentityLink.setDateOfBirth(dateOfBirth); - tempIdentityLink.setFamilyName(familyName); - tempIdentityLink.setGivenName(givenName); - tempIdentityLink.setIdentificationType(identificationType); - tempIdentityLink.setIdentificationValue(identificationValue); - tempIdentityLink.setPrPerson(prPerson); - try { - tempIdentityLink.setSamlAssertion(session.getIdentityLink().getSamlAssertion()); - } catch (Exception e) { - throw new ValidateException("validator.64", null); - } - - } - - } - - // builds authentication data and stores it together with a SAML artifact - AuthenticationData authData = session.getAssertionAuthData(); //buildAuthenticationData(session, vsresp, replacementIdentityLink); - - - Element mandatePerson = tempIdentityLink.getPrPerson(); -// try { -// System.out.println("MANDATE: " + DOMUtils.serializeNode(mandatePerson)); -// } -// catch(Exception e) { -// e.printStackTrace(); -// } - String mandateData = null; - boolean useCondition = false; - int conditionLength = -1; - try { - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - boolean provideStammzahl = oaParam.getProvideStammzahl(); - useCondition = oaParam.getUseCondition(); - conditionLength = oaParam.getConditionLength(); - if (!provideStammzahl) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); + } catch (ParserConfigurationException e) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); + } catch (TransformerException e) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }, e); + } + } + + } + + /** + * + * @param session + * @param authConf + * @param oaParam + * @return + * @throws ConfigurationException + * @throws BuildException + * @throws ValidateException + */ + public String getCreateXMLSignatureRequestAuthBlockOrRedirect( + AuthenticationSession session, AuthConfigurationProvider 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 = AuthConfigurationProvider.getInstance(); + if (oaParam == null) + oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + + // if (!fromMandate) { + // BZ.., calculate bPK for signing to be already present in AuthBlock + IdentityLink identityLink = session.getIdentityLink(); + if (identityLink.getIdentificationType().equals( + Constants.URN_PREFIX_BASEID)) { + // only compute bPK if online application is a public service and we + // have the Stammzahl + String bpkBase64 = new BPKBuilder().buildBPK(identityLink + .getIdentificationValue(), session.getTarget()); + identityLink.setIdentificationValue(bpkBase64); + } + // ..BZ + // } + + // builds the AUTH-block + String authBlock = buildAuthenticationBlock(session, oaParam); + + // session.setAuthBlock(authBlock); + // builds the <CreateXMLSignatureRequest> + String[] transformsInfos = oaParam.getTransformsInfos(); + if ((transformsInfos == null) || (transformsInfos.length == 0)) { + // no OA specific transforms specified, use default ones + transformsInfos = authConf.getTransformsInfos(); + } + String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder() + .build(authBlock, oaParam.getKeyBoxIdentifier(), + transformsInfos, oaParam.getSlVersion12()); + 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><CreateXMLSignatureRequest></code> + */ + public String createXMLSignatureRequestForeignID(String sessionID, + X509Certificate cert) throws AuthenticationException, + BuildException, ParseException, ConfigurationException, + ValidateException, ServiceException { + + if (isEmpty(sessionID)) + throw new AuthenticationException("auth.10", new Object[] { + REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID }); + + AuthenticationSession session = getSession(sessionID); + + AuthConfigurationProvider authConf = AuthConfigurationProvider + .getInstance(); + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + + return getCreateXMLSignatureRequestForeigID(session, authConf, oaParam, + cert); + } + + public String getCreateXMLSignatureRequestForeigID( + AuthenticationSession session, AuthConfigurationProvider 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 = AuthConfigurationProvider.getInstance(); + if (oaParam == null) + oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + + Principal subject = cert.getSubjectDN(); + + String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder() + .buildForeignID(subject.toString(), oaParam, session); + return createXMLSignatureRequest; + } + + /** + * Processes an <code><CreateXMLSignatureResponse></code> sent by the + * security layer implementation.<br> + * <ul> + * <li>Validates given <code><CreateXMLSignatureResponse></code></li> + * <li>Parses response enclosed in + * <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> + */ + public X509Certificate verifyXMLSignature(String sessionID, + Map createXMLSignatureResponseParameters) + throws AuthenticationException, BuildException, ParseException, + ConfigurationException, ValidateException, ServiceException { + + 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 }); + + AuthenticationSession session = getSession(sessionID); + /* + * if (session.getTimestampIdentityLink() != null) throw new + * AuthenticationException("auth.01", new Object[] { sessionID }); + */ + // session.setTimestampIdentityLink(); + AuthConfigurationProvider authConf = AuthConfigurationProvider + .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(); + + // int code = verifyXMLSignatureResponse.getSignatureCheckCode(); + + return verifyXMLSignatureResponse.getX509certificate(); + + } + + /** + * Processes an <code><CreateXMLSignatureResponse></code> sent by the + * security layer implementation.<br> + * <ul> + * <li>Validates given <code><CreateXMLSignatureResponse></code></li> + * <li>Parses response enclosed in + * <code><CreateXMLSignatureResponse></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 readInfoboxResponseParameters + * The parameters from the response returned from the BKU + * including the <code><ReadInfoboxResponse></code> + */ + public X509Certificate getCertificate(String sessionID, + Map readInfoboxResponseParameters) throws AuthenticationException, + BuildException, ParseException, ConfigurationException, + ValidateException, ServiceException { + + 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(); + + return cert; + + } + + /** + * Builds an authentication block <code><saml:Assertion></code> from + * given session data. + * + * @param session + * authentication session + * + * @return <code><saml:Assertion></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 = identityLink.getIdentificationValue(); + String identificationType = identityLink.getIdentificationType(); + + String issueInstant = DateTimeUtils.buildDateTime(Calendar + .getInstance(), oaParam.getUseUTC()); + 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(); + String oaURL = session.getPublicOAURLPrefix().replaceAll("&", "&"); + List extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); + String authBlock = new AuthenticationBlockAssertionBuilder() + .buildAuthBlock(issuer, issueInstant, authURL, target, + targetFriendlyName, identificationValue, + identificationType, oaURL, gebDat, + extendedSAMLAttributes, session); + + 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 infoboxReadResponseParams + * The parameters returned from the BKU as response to an infobox + * read request (including the infobox tokens to be verified). + * @param hideStammzahl + * Indicates whether source pins (<code>Stammzahl</code>en) + * should be hidden in any SAML attribute that may be returned by + * a validator. + * + * @throws AuthenticationException + * If the verification of at least one infobox fails. + * @throws ConfigurationException + * If the OAuthParameter cannot be extracted. + */ + private void verifyInfoboxes(AuthenticationSession session, + Map infoboxReadResponseParams, boolean hideStammzahl) + throws ValidateException, ConfigurationException { + + AuthConfigurationProvider authConfigurationProvider = AuthConfigurationProvider + .getInstance(); + // get the default VerifyInfobox parameters + Map defaultInfoboxParameters = null; + VerifyInfoboxParameters defaultVerifyInfoboxParameters = authConfigurationProvider + .getDefaultVerifyInfoboxParameters(); + if (defaultVerifyInfoboxParameters != null) { + defaultInfoboxParameters = defaultVerifyInfoboxParameters + .getInfoboxParameters(); + } + // get the OA specific VerifyInfobox parameters + Map infoboxParameters = null; + OAAuthParameter oaParam = authConfigurationProvider + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + VerifyInfoboxParameters verifyInfoboxParameters = oaParam + .getVerifyInfoboxParameters(); + session.setExtendedSAMLAttributesAUTH(new Vector()); // Initialize SAML + // Attributes + session.setExtendedSAMLAttributesOA(new Vector()); + + // System.out.println("SAML set: " + + // session.getExtendedSAMLAttributesAUTH().size()); + + if (verifyInfoboxParameters != null) { + + infoboxParameters = verifyInfoboxParameters.getInfoboxParameters(); + // get the list of infobox identifiers + List identifiers = verifyInfoboxParameters.getIdentifiers(); + if (identifiers != null) { + // step through the identifiers and verify the infoboxes + Iterator it = identifiers.iterator(); + while (it.hasNext()) { + String identifier = (String) it.next(); + // get the infobox read response from the map of parameters + String infoboxReadResponse = (String) infoboxReadResponseParams + .get(identifier); + // get the configuration parameters + VerifyInfoboxParameter verifyInfoboxParameter = null; + Object object = infoboxParameters.get(identifier); + // if not present, use default + if ((object == null) && (defaultInfoboxParameters != null)) { + object = defaultInfoboxParameters.get(identifier); + } + if (object != null) { + verifyInfoboxParameter = (VerifyInfoboxParameter) object; + } + if (infoboxReadResponse != null) { + if (verifyInfoboxParameter == null) { + // should not happen because of the pushinfobox + // mechanism; check it anyway + Logger.error("No validator for verifying \"" + + identifier + "\"-infobox configured."); + throw new ValidateException("validator.41", + new Object[] { identifier }); + } else { + String friendlyName = verifyInfoboxParameter + .getFriendlyName(); + boolean isParepRequest = false; + + // parse the infobox read reponse + List infoboxTokenList = null; + try { + infoboxTokenList = ExtendedInfoboxReadResponseParser + .parseInfoboxReadResponse( + infoboxReadResponse, + friendlyName); + } catch (ParseException e) { + Logger + .error("InfoboxReadResponse for \"" + + identifier + + "\"-infobox could not be parsed successfully: " + + e.getMessage()); + throw new ValidateException("validator.43", + new Object[] { friendlyName }); + } + // set compatibility mode for mandates infobox and + // all infoboxes (it is possible to be a parep + // infobox) + // session.setMandateCompatibilityMode(ParepConfiguration.isMandateCompatibilityMode(verifyInfoboxParameter.getApplicationSpecificParams())); + // check for party representation in mandates + // infobox + if (Constants.INFOBOXIDENTIFIER_MANDATES + .equalsIgnoreCase(identifier) + && !((infoboxTokenList == null || infoboxTokenList + .size() == 0))) { + // We need app specific parameters + if (null == verifyInfoboxParameter + .getApplicationSpecificParams()) { + throw new ValidateException("validator.66", + new Object[] { friendlyName }); + } + Element mandate = ParepValidator + .extractPrimaryToken(infoboxTokenList); + // ParepUtils.serializeElement(mandate, + // System.out); + String mandateID = ParepUtils + .extractRepresentativeID(mandate); + if (!isEmpty(mandateID) + && ("*".equals(mandateID) || mandateID + .startsWith(MOAIDAuthConstants.PARTY_REPRESENTATION_OID_NUMBER))) { + isParepRequest = true; + } + if (!isParepRequest) { + // if mandates validator is disabled we must + // throw an error in this case + if (!ParepUtils + .isValidatorEnabled(verifyInfoboxParameter + .getApplicationSpecificParams())) { + throw new ValidateException( + "validator.60", + new Object[] { friendlyName }); + } + } + } + + // get the class for validating the infobox + InfoboxValidator infoboxValidator = null; + try { + Class validatorClass = null; + if (isParepRequest) { + // Mandates infobox in party representation + // mode + validatorClass = Class + .forName("at.gv.egovernment.moa.id.auth.validator.parep.ParepValidator"); + } else { + validatorClass = Class + .forName(verifyInfoboxParameter + .getValidatorClassName()); + } + infoboxValidator = (InfoboxValidator) validatorClass + .newInstance(); + } catch (Exception e) { + Logger + .error("Could not load validator class \"" + + verifyInfoboxParameter + .getValidatorClassName() + + "\" for \"" + + identifier + + "\"-infobox: " + + e.getMessage()); + throw new ValidateException("validator.42", + new Object[] { friendlyName }); + } + Logger + .debug("Successfully loaded validator class \"" + + verifyInfoboxParameter + .getValidatorClassName() + + "\" for \"" + + identifier + + "\"-infobox."); + // build the parameters for validating the infobox + InfoboxValidatorParams infoboxValidatorParams = InfoboxValidatorParamsBuilder + .buildInfoboxValidatorParams(session, + verifyInfoboxParameter, + infoboxTokenList, oaParam); + + // now validate the infobox + InfoboxValidationResult infoboxValidationResult = null; + try { + infoboxValidationResult = infoboxValidator + .validate(infoboxValidatorParams); + } catch (ValidateException e) { + Logger.error("Error validating " + identifier + + " infobox:" + e.getMessage()); + throw new ValidateException("validator.44", + new Object[] { friendlyName }); + } + if (!infoboxValidationResult.isValid()) { + Logger.info("Validation of " + identifier + + " infobox failed."); + throw new ValidateException("validator.40", + new Object[] { + friendlyName, + infoboxValidationResult + .getErrorMessage() }); + } + + Logger.info(identifier + + " infobox successfully validated."); + // store the validator for post processing + session.addInfoboxValidator(identifier, + friendlyName, infoboxValidator); + + // get the SAML attributes to be appended to the + // AUTHBlock or to the final + // SAML Assertion + AddAdditionalSAMLAttributes(session, + infoboxValidationResult + .getExtendedSamlAttributes(), + identifier, friendlyName); + } + } else { + if ((verifyInfoboxParameter != null) + && (verifyInfoboxParameter.isRequired())) { + Logger + .info("Infobox \"" + + identifier + + "\" is required, but not returned from the BKU"); + throw new ValidateException("validator.48", + new Object[] { verifyInfoboxParameter + .getFriendlyName() }); + } + Logger.debug("Infobox \"" + identifier + + "\" not returned from BKU."); + } + } + } + } + } + + /** + * 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 setExtendedSAMLAttributeForMandates( + AuthenticationSession session, MISMandate mandate, + boolean business, boolean provideStammzahl) + throws ValidateException, ConfigurationException, SAXException, + IOException, ParserConfigurationException, TransformerException { + + ExtendedSAMLAttribute[] extendedSamlAttributes = addExtendedSamlAttributes( + mandate, business, provideStammzahl); + + AddAdditionalSAMLAttributes(session, extendedSamlAttributes, + "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"); + + } + + /** + * Intermediate processing of the infoboxes. The first pending infobox + * validator may validate the provided input + * + * @param session + * The current authentication session + * @param parameters + * The parameters got returned by the user input fields + */ + public static void processInput(AuthenticationSession session, + Map parameters) throws ValidateException { + + // post processing of the infoboxes + Iterator iter = session.getInfoboxValidatorIterator(); + if (iter != null) { + while (iter.hasNext()) { + Vector infoboxValidatorVector = (Vector) iter.next(); + InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector + .get(2); + if (!ParepUtils.isEmpty(infoboxvalidator.getForm())) { + String identifier = (String) infoboxValidatorVector.get(0); + String friendlyName = (String) infoboxValidatorVector + .get(1); + InfoboxValidationResult infoboxValidationResult = null; + try { + infoboxValidationResult = infoboxvalidator + .validate(parameters); + } catch (ValidateException e) { + Logger.error("Error validating " + identifier + + " infobox:" + e.getMessage()); + throw new ValidateException("validator.44", + new Object[] { friendlyName }); + } + if (!infoboxValidationResult.isValid()) { + Logger.info("Validation of " + identifier + + " infobox failed."); + throw new ValidateException("validator.40", + new Object[] { + friendlyName, + infoboxValidationResult + .getErrorMessage() }); + } + AddAdditionalSAMLAttributes( + session, + infoboxValidationResult.getExtendedSamlAttributes(), + identifier, friendlyName); + } + } + } + } + + /** + * 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 oaAttributes = session.getExtendedSAMLAttributesOA(); + if (oaAttributes == null) + oaAttributes = new Vector(); + List authAttributes = session.getExtendedSAMLAttributesAUTH(); + if (authAttributes == null) + authAttributes = new Vector(); + 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 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, MISMandate mandate) throws ValidateException + // { + // + // List oaAttributes = session.getExtendedSAMLAttributesOA(); + // if (oaAttributes==null) oaAttributes = new Vector(); + // List authAttributes = session.getExtendedSAMLAttributesAUTH(); + // if (authAttributes==null) authAttributes = new Vector(); + // + // + // addExtendedSamlAttributes(authAttributes, mandate); + // + // 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 + */ + + private static ExtendedSAMLAttribute[] addExtendedSamlAttributes( + MISMandate mandate, boolean business, boolean provideStammzahl) + throws SAXException, IOException, ParserConfigurationException, + TransformerException { + Vector extendedSamlAttributes = new Vector(); + + extendedSamlAttributes.clear(); + + // extendedSamlAttributes.add(new + // ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_RAW, + // mandate, SZRGWConstants.MANDATE_NS, + // ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + + // 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); + + // first check if physical person + // Element name = (Element) XPathAPI.selectSingleNode(mandator, + // "descendant-or-self::pr:Name/pr:GivenName", nameSpaceNode); + // String mandatorname = ParepUtils.extractMandatorName(mandator); + + // extendedSamlAttributes.add(new + // ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_NAME, + // mandatorname, SZRGWConstants.MANDATE_NS, + // ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); + // Geburtsdatum + // String dob = ParepUtils.extractMandatorDateOfBirth(mandator); + // if (dob != null && !"".equals(dob)) { + // extendedSamlAttributes.add(new + // ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_DOB, dob, + // SZRGWConstants.MANDATE_NS, + // ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); + // } + + // Mandate + extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( + ParepValidator.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( + ParepValidator.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( + ParepValidator.EXT_SAML_MANDATE_WBPK, wbpk, + SZRGWConstants.MANDATE_NS, + ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); + } + } + + // String oid = mandate.getProfRep(); + // if (oid != null) { + // String oidDescription = mandate.getTextualDescriptionOfOID(); + // extendedSamlAttributes.add(new + // ExtendedSAMLAttributeImpl(ParepValidator.EXT_SAML_MANDATE_OIDTEXTUALDESCRIPTION, + // oidDescription, 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 extendedSamlAttributes = new Vector(); + + extendedSamlAttributes.clear(); + + // RepresentationType + extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( + ParepValidator.EXT_SAML_MANDATE_REPRESENTATIONTYPE, + ParepValidator.EXT_SAML_MANDATE_REPRESENTATIONTEXT, + SZRGWConstants.MANDATE_NS, + ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + + String oid = mandate.getProfRep(); + + if (oid != null) { + extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( + ParepValidator.EXT_SAML_MANDATE_OID, oid, + SZRGWConstants.MANDATE_NS, + ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + String oidDescription = mandate.getTextualDescriptionOfOID(); + extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( + ParepValidator.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); + return doc.getDocumentElement(); + } + + private static void replaceExtendedSAMLAttribute(List attributes, + ExtendedSAMLAttribute samlAttribute) { + if (null == attributes) { + attributes = new Vector(); + } 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><CreateXMLSignatureResponse></code> sent by the + * security layer implementation.<br> + * <ul> + * <li>Validates given <code><CreateXMLSignatureResponse></code></li> + * <li>Parses <code><CreateXMLSignatureResponse></code> for error + * codes</li> + * <li>Parses authentication block enclosed in + * <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> + * @return SAML artifact needed for retrieving authentication data, encoded + * BASE64 + */ + public String verifyAuthenticationBlock(String sessionID, + String xmlCreateXMLSignatureReadResponse) + throws AuthenticationException, BuildException, ParseException, + ConfigurationException, ServiceException, ValidateException { + + if (isEmpty(sessionID)) + 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 }); + AuthenticationSession session = getSession(sessionID); + AuthConfigurationProvider authConf = AuthConfigurationProvider + .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> + new CreateXMLSignatureResponseValidator().validate(csresp, session); + // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call + String[] vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); + String tpid = authConf.getMoaSpAuthBlockTrustProfileID(); + Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp, + vtids, tpid); + // debug output + + // invokes the call + Element domVsresp = new SignatureVerificationInvoker() + .verifyXMLSignature(domVsreq); + // debug output + + // 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())); + } + } + } + + // validates the <VerifyXMLSignatureResponse> + VerifyXMLSignatureResponseValidator.getInstance().validate(vsresp, + null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, + false); + + // TODO See Bug #144 + // Compare AuthBlock Data with information stored in session, especially + // date and time + + // compares the public keys from the identityLink with the AuthBlock + VerifyXMLSignatureResponseValidator.getInstance().validateCertificate( + vsresp, session.getIdentityLink()); + + // post processing of the infoboxes + Iterator iter = session.getInfoboxValidatorIterator(); + boolean formpending = false; + if (iter != null) { + while (!formpending && iter.hasNext()) { + Vector infoboxValidatorVector = (Vector) iter.next(); + String identifier = (String) infoboxValidatorVector.get(0); + String friendlyName = (String) infoboxValidatorVector.get(1); + InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector + .get(2); + InfoboxValidationResult infoboxValidationResult = null; + try { + infoboxValidationResult = infoboxvalidator.validate(csresp + .getSamlAssertion()); + } catch (ValidateException e) { + Logger.error("Error validating " + identifier + " infobox:" + + e.getMessage()); + throw new ValidateException("validator.44", + new Object[] { friendlyName }); + } + if (!infoboxValidationResult.isValid()) { + Logger.info("Validation of " + identifier + + " infobox failed."); + throw new ValidateException("validator.40", new Object[] { + friendlyName, + infoboxValidationResult.getErrorMessage() }); + } + String form = infoboxvalidator.getForm(); + if (ParepUtils.isEmpty(form)) { + AddAdditionalSAMLAttributes( + session, + infoboxValidationResult.getExtendedSamlAttributes(), + identifier, friendlyName); + } else { + return "Redirect to Input Processor"; + } + } + } + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + boolean useUTC = oaParam.getUseUTC(); + boolean useCondition = oaParam.getUseCondition(); + int conditionLength = oaParam.getConditionLength(); + + // builds authentication data and stores it together with a SAML + // artifact + AuthenticationData authData = buildAuthenticationData(session, vsresp, + useUTC); + + if (session.getUseMandate()) { + // mandate mode + // session.setAssertionAuthBlock(assertionAuthBlock) + + // set signer certificate + session.setSignerCertificate(vsresp.getX509certificate()); + + return null; + } else { + + String samlAssertion = new AuthenticationDataAssertionBuilder() + .build(authData, session.getAssertionPrPerson(), session + .getAssertionAuthBlock(), session + .getAssertionIlAssertion(), session.getBkuURL(), + session.getAssertionSignerCertificateBase64(), + session.getAssertionBusinessService(), session + .getExtendedSAMLAttributesOA(), + useCondition, conditionLength); + authData.setSamlAssertion(samlAssertion); + + String assertionFile = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.WriteAssertionToFile"); + if (!ParepUtils.isEmpty(assertionFile)) + try { + ParepUtils.saveStringToFile(samlAssertion, new File( + assertionFile)); + } catch (IOException e) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", e.toString() }, e); + } + + String samlArtifact = new SAMLArtifactBuilder().build(session + .getAuthURL(), session.getSessionID(), session + .getSourceID()); + storeAuthenticationData(samlArtifact, authData); + + // invalidates the authentication session + sessionStore.remove(sessionID); + Logger.info("Anmeldedaten zu MOASession " + sessionID + + " angelegt, SAML Artifakt " + samlArtifact); + return samlArtifact; + + } + + } + + /** + * Processes a <code><CreateXMLSignatureResponse></code> sent by the + * security layer implementation.<br> + * <ul> + * <li>Validates given <code><CreateXMLSignatureResponse></code></li> + * <li>Parses <code><CreateXMLSignatureResponse></code> for error + * codes</li> + * <li>Parses authentication block enclosed in + * <code><CreateXMLSignatureResponse></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><CreateXMLSignatureResponse></code> + * @return SAML artifact needed for retrieving authentication data, encoded + * BASE64 + */ + public String verifyAuthenticationBlockMandate(String sessionID, + Element mandate) throws AuthenticationException, BuildException, + ParseException, ConfigurationException, ServiceException, + ValidateException { + + if (isEmpty(sessionID)) + throw new AuthenticationException("auth.10", new Object[] { + REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID }); + AuthenticationSession session = getSession(sessionID); + // AuthConfigurationProvider authConf = + // AuthConfigurationProvider.getInstance(); + + IdentityLink tempIdentityLink = null; + + if (session.getUseMandate()) { + tempIdentityLink = new IdentityLink(); + Element mandator = ParepUtils.extractMandator(mandate); + String dateOfBirth = ""; + Element prPerson = null; + String familyName = ""; + String givenName = ""; + String identificationType = ""; + String identificationValue = ""; + if (mandator != null) { + boolean physical = ParepUtils.isPhysicalPerson(mandator); + if (physical) { + familyName = ParepUtils.extractText(mandator, + "descendant-or-self::pr:Name/pr:FamilyName/text()"); + givenName = ParepUtils.extractText(mandator, + "descendant-or-self::pr:Name/pr:GivenName/text()"); + dateOfBirth = ParepUtils + .extractMandatorDateOfBirth(mandator); + } else { + familyName = ParepUtils.extractMandatorFullName(mandator); + } + identificationType = ParepUtils.getIdentification(mandator, + "Type"); + identificationValue = ParepUtils.extractMandatorWbpk(mandator); + prPerson = ParepUtils.extractPrPersonOfMandate(mandate); + if (physical + && session.getBusinessService() + && identificationType != null + && Constants.URN_PREFIX_BASEID + .equals(identificationType)) { + // now we calculate the wbPK and do so if we got it from the + // BKU + identificationType = Constants.URN_PREFIX_WBPK + "+" + + session.getDomainIdentifier(); + identificationValue = new BPKBuilder().buildWBPK( + identificationValue, session.getDomainIdentifier()); + ParepUtils + .HideStammZahlen(prPerson, true, null, null, true); + } + + tempIdentityLink.setDateOfBirth(dateOfBirth); + tempIdentityLink.setFamilyName(familyName); + tempIdentityLink.setGivenName(givenName); + tempIdentityLink.setIdentificationType(identificationType); + tempIdentityLink.setIdentificationValue(identificationValue); + tempIdentityLink.setPrPerson(prPerson); + try { + tempIdentityLink.setSamlAssertion(session.getIdentityLink() + .getSamlAssertion()); + } catch (Exception e) { + throw new ValidateException("validator.64", null); + } + + } + + } + + // builds authentication data and stores it together with a SAML + // artifact + AuthenticationData authData = session.getAssertionAuthData(); // buildAuthenticationData(session, + // vsresp, + // replacementIdentityLink); + + Element mandatePerson = tempIdentityLink.getPrPerson(); + // try { + // System.out.println("MANDATE: " + + // DOMUtils.serializeNode(mandatePerson)); + // } + // catch(Exception e) { + // e.printStackTrace(); + // } + String mandateData = null; + boolean useCondition = false; + int conditionLength = -1; + try { + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + boolean provideStammzahl = oaParam.getProvideStammzahl(); + useCondition = oaParam.getUseCondition(); + conditionLength = oaParam.getConditionLength(); + String isPrPerson = mandatePerson.getAttribute("xsi:type"); - + if (!StringUtils.isEmpty(isPrPerson)) { if (isPrPerson.equalsIgnoreCase("pr:PhysicalPerson")) { - Node prIdentification = mandatePerson.getFirstChild(); - prIdentification.getFirstChild().setTextContent(""); -// Element.appendChild(Document.createTextNode(String)); -// prIdentification.getFirstChild(). - } + Element prIdentification = (Element) mandatePerson + .getElementsByTagNameNS(Constants.PD_NS_URI, + "Identification").item(0); + String baseid = getBaseId(mandatePerson); + Element identificationBpK = createIdentificationBPK(mandatePerson, + baseid, session.getTarget()); + + if (!provideStammzahl) { + prIdentification.getFirstChild().setTextContent(""); + } + + mandatePerson.insertBefore(identificationBpK, + prIdentification); + } } - + + mandateData = DOMUtils.serializeNode(mandatePerson); + + } catch (TransformerException e1) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }); + } catch (IOException e1) { + throw new AuthenticationException("auth.16", + new Object[] { GET_MIS_SESSIONID }); } - mandateData = DOMUtils.serializeNode(mandatePerson); - } catch (TransformerException e1) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}); - } catch (IOException e1) { - throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID}); + + String samlAssertion = new AuthenticationDataAssertionBuilder() + .buildMandate(authData, session.getAssertionPrPerson(), + mandateData, session.getAssertionAuthBlock(), session + .getAssertionIlAssertion(), + session.getBkuURL(), session + .getAssertionSignerCertificateBase64(), session + .getAssertionBusinessService(), session + .getSourceID(), session + .getExtendedSAMLAttributesOA(), useCondition, + conditionLength); + authData.setSamlAssertion(samlAssertion); + + String assertionFile = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.WriteAssertionToFile"); + if (!ParepUtils.isEmpty(assertionFile)) + try { + ParepUtils.saveStringToFile(samlAssertion, new File( + assertionFile)); + } catch (IOException e) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", e.toString() }, e); + } + + String samlArtifact = new SAMLArtifactBuilder().build(session + .getAuthURL(), session.getSessionID(), session.getSourceID()); + storeAuthenticationData(samlArtifact, authData); + + // invalidates the authentication session + sessionStore.remove(sessionID); + Logger.info("Anmeldedaten zu MOASession " + sessionID + + " angelegt, SAML Artifakt " + samlArtifact); + return samlArtifact; + } - - - String samlAssertion = - new AuthenticationDataAssertionBuilder().buildMandate( - authData, - session.getAssertionPrPerson(), - mandateData, - session.getAssertionAuthBlock(), - session.getAssertionIlAssertion(), - session.getBkuURL(), - session.getAssertionSignerCertificateBase64(), - session.getAssertionBusinessService(), - session.getSourceID(), - session.getExtendedSAMLAttributesOA(), - useCondition, - conditionLength); - authData.setSamlAssertion(samlAssertion); - - String assertionFile = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter("AuthenticationServer.WriteAssertionToFile"); - if (!ParepUtils.isEmpty(assertionFile)) - try { - ParepUtils.saveStringToFile(samlAssertion, new File(assertionFile)); - } catch (IOException e) { - throw new BuildException( - "builder.00", - new Object[] { "AuthenticationData", e.toString()}, - e); - } - - String samlArtifact = - new SAMLArtifactBuilder().build(session.getAuthURL(), session.getSessionID(), session.getSourceID()); - storeAuthenticationData(samlArtifact, authData); - - // invalidates the authentication session - sessionStore.remove(sessionID); - Logger.info( - "Anmeldedaten zu MOASession " + sessionID + " angelegt, SAML Artifakt " + samlArtifact); - return samlArtifact; - - } - - /** - * Gets the foreign authentication data.<br> - * <ul> - * <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 - * @return SAML artifact needed for retrieving authentication data, encoded BASE64 - */ - public String getForeignAuthenticationData( - String sessionID) - throws - AuthenticationException, - BuildException, - ParseException, - ConfigurationException, - ServiceException, - ValidateException { - - if (isEmpty(sessionID)) - throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID}); - - AuthenticationSession session = getSession(sessionID); - //AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); - try { - String serializedAssertion = DOMUtils.serializeNode(session.getIdentityLink().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}); - } - // post processing of the infoboxes - Iterator iter = session.getInfoboxValidatorIterator(); - boolean formpending = false; - if (iter != null) { - while (!formpending && iter.hasNext()) { - Vector infoboxValidatorVector = (Vector) iter.next(); - String identifier = (String) infoboxValidatorVector.get(0); - String friendlyName = (String) infoboxValidatorVector.get(1); - InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector.get(2); - InfoboxValidationResult infoboxValidationResult = null; - try { - infoboxValidationResult = infoboxvalidator.validate(session.getIdentityLink().getSamlAssertion()); - } catch (ValidateException e) { - Logger.error("Error validating " + identifier + " infobox:" + e.getMessage()); - throw new ValidateException( - "validator.44", new Object[] {friendlyName}); - } - if (!infoboxValidationResult.isValid()) { - Logger.info("Validation of " + identifier + " infobox failed."); - throw new ValidateException( - "validator.40", new Object[] {friendlyName, infoboxValidationResult.getErrorMessage()}); - } - String form = infoboxvalidator.getForm(); - if (ParepUtils.isEmpty(form)) { - AddAdditionalSAMLAttributes(session, infoboxValidationResult.getExtendedSamlAttributes(), identifier, friendlyName); - } else { - return "Redirect to Input Processor"; - } - } - } - - VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponse(); - X509Certificate cert = session.getSignerCertificate(); - vsresp.setX509certificate(cert); - - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - boolean useUTC = oaParam.getUseUTC(); - boolean useCondition = oaParam.getUseCondition(); - int conditionLength = oaParam.getConditionLength(); - AuthenticationData authData = buildAuthenticationData(session, vsresp, useUTC); - - - String samlAssertion = - new AuthenticationDataAssertionBuilder().build( - authData, - session.getAssertionPrPerson(), - session.getAssertionAuthBlock(), - session.getAssertionIlAssertion(), - session.getBkuURL(), - session.getAssertionSignerCertificateBase64(), - session.getAssertionBusinessService(), - session.getExtendedSAMLAttributesOA(), - useCondition, - conditionLength); - authData.setSamlAssertion(samlAssertion); - - String assertionFile = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter("AuthenticationServer.WriteAssertionToFile"); - if (!ParepUtils.isEmpty(assertionFile)) + + private 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; + + } + + private 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>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 + * @return SAML artifact needed for retrieving authentication data, encoded + * BASE64 + */ + public String getForeignAuthenticationData(String sessionID) + throws AuthenticationException, BuildException, ParseException, + ConfigurationException, ServiceException, ValidateException { + + if (isEmpty(sessionID)) + throw new AuthenticationException("auth.10", new Object[] { + REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID }); + + AuthenticationSession session = getSession(sessionID); + // AuthConfigurationProvider authConf = + // AuthConfigurationProvider.getInstance(); try { - ParepUtils.saveStringToFile(samlAssertion, new File(assertionFile)); + String serializedAssertion = DOMUtils.serializeNode(session + .getIdentityLink().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 BuildException( - "builder.00", - new Object[] { "AuthenticationData", e.toString()}, - e); - } - - String samlArtifact = - new SAMLArtifactBuilder().build(session.getAuthURL(), session.getSessionID(), session.getSourceID()); - storeAuthenticationData(samlArtifact, authData); - - // invalidates the authentication session - sessionStore.remove(sessionID); - Logger.info( - "Anmeldedaten zu MOASession " + sessionID + " angelegt, SAML Artifakt " + samlArtifact); - - return samlArtifact; - } - - /** - * Builds the AuthenticationData object together with the - * corresponding <code><saml:Assertion></code> - * @param session authentication session - * @param verifyXMLSigResp VerifyXMLSignatureResponse from MOA-SP - * @return AuthenticationData object - * @throws ConfigurationException while accessing configuration data - * @throws BuildException while building the <code><saml:Assertion></code> - */ - private AuthenticationData buildAuthenticationData( - AuthenticationSession session, - VerifyXMLSignatureResponse verifyXMLSigResp, - boolean useUTC) - throws ConfigurationException, BuildException { - - IdentityLink identityLink = session.getIdentityLink(); - AuthenticationData authData = new AuthenticationData(); - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - boolean businessService = oaParam.getBusinessService(); - authData.setMajorVersion(1); - authData.setMinorVersion(0); - authData.setAssertionID(Random.nextRandom()); - authData.setIssuer(session.getAuthURL()); - authData.setIssueInstant(DateTimeUtils.buildDateTime(Calendar.getInstance(), useUTC)); - authData.setIdentificationType(identityLink.getIdentificationType()); - authData.setGivenName(identityLink.getGivenName()); - authData.setFamilyName(identityLink.getFamilyName()); - authData.setDateOfBirth(identityLink.getDateOfBirth()); - authData.setQualifiedCertificate(verifyXMLSigResp.isQualifiedCertificate()); - authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); - authData.setPublicAuthorityCode(verifyXMLSigResp.getPublicAuthorityCode()); - authData.setBkuURL(session.getBkuURL()); - authData.setUseUTC(oaParam.getUseUTC()); - boolean provideStammzahl = oaParam.getProvideStammzahl(); - if (provideStammzahl) { - authData.setIdentificationValue(identityLink.getIdentificationValue()); - } - String prPerson = new PersonDataBuilder().build(identityLink, provideStammzahl); - - try { - String signerCertificateBase64 = ""; - if (oaParam.getProvideCertifcate()) { - X509Certificate signerCertificate = verifyXMLSigResp.getX509certificate(); - if (signerCertificate != null) { - signerCertificateBase64 = Base64Utils.encode(signerCertificate.getEncoded()); - } else { - Logger.info("\"provideCertificate\" is \"true\", but no signer certificate available"); - } - } - authData.setSignerCertificate(signerCertificateBase64); - if (businessService) { - authData.setWBPK(identityLink.getIdentificationValue()); - } else { - authData.setBPK(identityLink.getIdentificationValue()); - - //BZ.., calculation of bPK already before sending AUTHBlock - /* - if (identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { - // only compute bPK if online application is a public service and we have the Stammzahl - String bpkBase64 = new BPKBuilder().buildBPK( - identityLink.getIdentificationValue(), - session.getTarget()); - authData.setBPK(bpkBase64); - }*/ - - } - String ilAssertion = - oaParam.getProvideIdentityLink() - ? identityLink.getSerializedSamlAssertion() - : ""; - if (!oaParam.getProvideStammzahl()) { - ilAssertion = StringUtils.replaceAll(ilAssertion, identityLink.getIdentificationValue(), ""); - } - String authBlock = oaParam.getProvideAuthBlock() ? session.getAuthBlock() : ""; - - session.setAssertionAuthBlock(authBlock); - session.setAssertionAuthData(authData); - session.setAssertionBusinessService(businessService); - session.setAssertionIlAssertion(ilAssertion); - session.setAssertionPrPerson(prPerson); - session.setAssertionSignerCertificateBase64(signerCertificateBase64); - - return authData; - - - } catch (Throwable ex) { - throw new BuildException( - "builder.00", - new Object[] { "AuthenticationData", ex.toString()}, - ex); - } - } - /** - * Retrieves <code>AuthenticationData</code> indexed by the SAML artifact. - * The <code>AuthenticationData</code> is deleted from the store upon end of this call. - * - * @return <code>AuthenticationData</code> - */ - public AuthenticationData getAuthenticationData(String samlArtifact) - throws AuthenticationException { - String assertionHandle; - try { - assertionHandle = new SAMLArtifactParser(samlArtifact).parseAssertionHandle(); - } catch (ParseException ex) { - throw new AuthenticationException("1205", new Object[] { samlArtifact, ex.toString()}); - } - AuthenticationData authData = null; - synchronized (authenticationDataStore) { - //System.out.println("assertionHandle: " + assertionHandle); - authData = (AuthenticationData) authenticationDataStore.get(assertionHandle); - if (authData == null) { - Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); - throw new AuthenticationException("1206", new Object[] { samlArtifact }); - } - boolean keepAssertion = false; - try { - String boolStr = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter("AuthenticationServer.KeepAssertion"); - if (null!=boolStr && boolStr.equalsIgnoreCase("true")) keepAssertion = true;//Only allowed for debug purposes!!! - } catch (ConfigurationException ex) { - throw new AuthenticationException("1205", new Object[] { samlArtifact, ex.toString()}); - } - if (!keepAssertion) { - authenticationDataStore.remove(assertionHandle); - } - } - long now = new Date().getTime(); - if (now - authData.getTimestamp().getTime() > authDataTimeOut) - throw new AuthenticationException("1207", new Object[] { samlArtifact }); - Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); - return authData; - } - /** - * Stores authentication data indexed by the assertion handle contained in the - * given saml artifact. - * @param samlArtifact SAML artifact - * @param authData authentication data - * @throws AuthenticationException when SAML artifact is invalid - */ - private void storeAuthenticationData(String samlArtifact, AuthenticationData authData) - throws AuthenticationException { - - try { - SAMLArtifactParser parser = new SAMLArtifactParser(samlArtifact); - // check type code 0x0001 - byte[] typeCode = parser.parseTypeCode(); - if (typeCode[0] != 0 || typeCode[1] != 1) - throw new AuthenticationException("auth.06", new Object[] { samlArtifact }); - String assertionHandle = parser.parseAssertionHandle(); - synchronized (authenticationDataStore) { - Logger.debug("Assertion stored for SAML Artifact: " + samlArtifact); - authenticationDataStore.put(assertionHandle, authData); - } - } catch (AuthenticationException ex) { - throw ex; - } catch (Throwable ex) { - throw new AuthenticationException("auth.06", new Object[] { samlArtifact }); - } - } - /** - * Creates a new session and puts it into the session store. - * - * @param id Session ID - * @return AuthenticationSession created - * @exception AuthenticationException - * thrown when an <code>AuthenticationSession</code> is running - * already for the given session ID - */ - private static AuthenticationSession newSession() throws AuthenticationException { - String sessionID = Random.nextRandom(); - AuthenticationSession newSession = new AuthenticationSession(sessionID); - synchronized (sessionStore) { - AuthenticationSession session = (AuthenticationSession) sessionStore.get(sessionID); - if (session != null) - throw new AuthenticationException("auth.01", new Object[] { sessionID }); - sessionStore.put(sessionID, newSession); - } - return newSession; - } - /** - * Retrieves a session from the session store. - * - * @param id session ID - * @return <code>AuthenticationSession</code> stored with given session ID, - * <code>null</code> if session ID unknown - */ - public static AuthenticationSession getSession(String id) throws AuthenticationException { - AuthenticationSession session = (AuthenticationSession) sessionStore.get(id); - if (session == null) - throw new AuthenticationException("auth.02", new Object[] { id }); - return session; - } - /** - * Cleans up expired session and authentication data stores. - */ - public void cleanup() { - long now = new Date().getTime(); - synchronized (sessionStore) { - Set keys = new HashSet(sessionStore.keySet()); - for (Iterator iter = keys.iterator(); iter.hasNext();) { - String sessionID = (String) iter.next(); - AuthenticationSession session = (AuthenticationSession) sessionStore.get(sessionID); - if (now - session.getTimestampStart().getTime() > sessionTimeOut) { - Logger.info( - MOAIDMessageProvider.getInstance().getMessage( - "cleaner.02", - new Object[] { sessionID })); - sessionStore.remove(sessionID); - } - } - } - synchronized (authenticationDataStore) { - Set keys = new HashSet(authenticationDataStore.keySet()); - for (Iterator iter = keys.iterator(); iter.hasNext();) { - String samlAssertionHandle = (String) iter.next(); - AuthenticationData authData = (AuthenticationData) authenticationDataStore.get(samlAssertionHandle); - if (now - authData.getTimestamp().getTime() > authDataTimeOut) { - Logger.info( - MOAIDMessageProvider.getInstance().getMessage( - "cleaner.03", - new Object[] { authData.getAssertionID() })); - authenticationDataStore.remove(samlAssertionHandle); - } - } - } - } - - /** - * Sets the sessionTimeOut. - * @param seconds Time out of the session in seconds - */ - public void setSecondsSessionTimeOut(long seconds) { - sessionTimeOut = 1000 * seconds; - } - /** - * Sets the authDataTimeOut. - * @param seconds Time out for signing AuthData in seconds - */ - public void setSecondsAuthDataTimeOut(long seconds) { - authDataTimeOut = 1000 * seconds; - } - - /** - * 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) - */ - private 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; - } + throw new ParseException("parser.04", new Object[] { + REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE }); + } + // post processing of the infoboxes + Iterator iter = session.getInfoboxValidatorIterator(); + boolean formpending = false; + if (iter != null) { + while (!formpending && iter.hasNext()) { + Vector infoboxValidatorVector = (Vector) iter.next(); + String identifier = (String) infoboxValidatorVector.get(0); + String friendlyName = (String) infoboxValidatorVector.get(1); + InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector + .get(2); + InfoboxValidationResult infoboxValidationResult = null; + try { + infoboxValidationResult = infoboxvalidator.validate(session + .getIdentityLink().getSamlAssertion()); + } catch (ValidateException e) { + Logger.error("Error validating " + identifier + " infobox:" + + e.getMessage()); + throw new ValidateException("validator.44", + new Object[] { friendlyName }); + } + if (!infoboxValidationResult.isValid()) { + Logger.info("Validation of " + identifier + + " infobox failed."); + throw new ValidateException("validator.40", new Object[] { + friendlyName, + infoboxValidationResult.getErrorMessage() }); + } + String form = infoboxvalidator.getForm(); + if (ParepUtils.isEmpty(form)) { + AddAdditionalSAMLAttributes( + session, + infoboxValidationResult.getExtendedSamlAttributes(), + identifier, friendlyName); + } else { + return "Redirect to Input Processor"; + } + } + } + + VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponse(); + X509Certificate cert = session.getSignerCertificate(); + vsresp.setX509certificate(cert); + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + boolean useUTC = oaParam.getUseUTC(); + boolean useCondition = oaParam.getUseCondition(); + int conditionLength = oaParam.getConditionLength(); + AuthenticationData authData = buildAuthenticationData(session, vsresp, + useUTC); + + String samlAssertion = new AuthenticationDataAssertionBuilder().build( + authData, session.getAssertionPrPerson(), session + .getAssertionAuthBlock(), session + .getAssertionIlAssertion(), session.getBkuURL(), + session.getAssertionSignerCertificateBase64(), session + .getAssertionBusinessService(), session + .getExtendedSAMLAttributesOA(), useCondition, + conditionLength); + authData.setSamlAssertion(samlAssertion); + + String assertionFile = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.WriteAssertionToFile"); + if (!ParepUtils.isEmpty(assertionFile)) + try { + ParepUtils.saveStringToFile(samlAssertion, new File( + assertionFile)); + } catch (IOException e) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", e.toString() }, e); + } + + String samlArtifact = new SAMLArtifactBuilder().build(session + .getAuthURL(), session.getSessionID(), session.getSourceID()); + storeAuthenticationData(samlArtifact, authData); + + // invalidates the authentication session + sessionStore.remove(sessionID); + Logger.info("Anmeldedaten zu MOASession " + sessionID + + " angelegt, SAML Artifakt " + samlArtifact); + + return samlArtifact; + } + + /** + * Builds the AuthenticationData object together with the corresponding + * <code><saml:Assertion></code> + * + * @param session + * authentication session + * @param verifyXMLSigResp + * VerifyXMLSignatureResponse from MOA-SP + * @return AuthenticationData object + * @throws ConfigurationException + * while accessing configuration data + * @throws BuildException + * while building the <code><saml:Assertion></code> + */ + private AuthenticationData buildAuthenticationData( + AuthenticationSession session, + VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC) + throws ConfigurationException, BuildException { + + IdentityLink identityLink = session.getIdentityLink(); + AuthenticationData authData = new AuthenticationData(); + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + boolean businessService = oaParam.getBusinessService(); + authData.setMajorVersion(1); + authData.setMinorVersion(0); + authData.setAssertionID(Random.nextRandom()); + authData.setIssuer(session.getAuthURL()); + authData.setIssueInstant(DateTimeUtils.buildDateTime(Calendar + .getInstance(), useUTC)); + authData.setIdentificationType(identityLink.getIdentificationType()); + authData.setGivenName(identityLink.getGivenName()); + authData.setFamilyName(identityLink.getFamilyName()); + authData.setDateOfBirth(identityLink.getDateOfBirth()); + authData.setQualifiedCertificate(verifyXMLSigResp + .isQualifiedCertificate()); + authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); + authData.setPublicAuthorityCode(verifyXMLSigResp + .getPublicAuthorityCode()); + authData.setBkuURL(session.getBkuURL()); + authData.setUseUTC(oaParam.getUseUTC()); + boolean provideStammzahl = oaParam.getProvideStammzahl(); + if (provideStammzahl) { + authData.setIdentificationValue(identityLink + .getIdentificationValue()); + } + String prPerson = new PersonDataBuilder().build(identityLink, + provideStammzahl); + + try { + String signerCertificateBase64 = ""; + if (oaParam.getProvideCertifcate()) { + X509Certificate signerCertificate = verifyXMLSigResp + .getX509certificate(); + if (signerCertificate != null) { + signerCertificateBase64 = Base64Utils + .encode(signerCertificate.getEncoded()); + } else { + Logger + .info("\"provideCertificate\" is \"true\", but no signer certificate available"); + } + } + authData.setSignerCertificate(signerCertificateBase64); + if (businessService) { + authData.setWBPK(identityLink.getIdentificationValue()); + } else { + authData.setBPK(identityLink.getIdentificationValue()); + + // BZ.., calculation of bPK already before sending AUTHBlock + /* + * if(identityLink.getIdentificationType().equals(Constants. + * URN_PREFIX_BASEID)) { // only compute bPK if online + * application is a public service and we have the Stammzahl + * String bpkBase64 = new BPKBuilder().buildBPK( + * identityLink.getIdentificationValue(), session.getTarget()); + * authData.setBPK(bpkBase64); } + */ + + } + String ilAssertion = oaParam.getProvideIdentityLink() ? identityLink + .getSerializedSamlAssertion() + : ""; + if (!oaParam.getProvideStammzahl()) { + ilAssertion = StringUtils.replaceAll(ilAssertion, identityLink + .getIdentificationValue(), ""); + } + String authBlock = oaParam.getProvideAuthBlock() ? session + .getAuthBlock() : ""; + + session.setAssertionAuthBlock(authBlock); + session.setAssertionAuthData(authData); + session.setAssertionBusinessService(businessService); + session.setAssertionIlAssertion(ilAssertion); + session.setAssertionPrPerson(prPerson); + session + .setAssertionSignerCertificateBase64(signerCertificateBase64); + + return authData; + + } catch (Throwable ex) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", ex.toString() }, ex); + } + } + + /** + * Retrieves <code>AuthenticationData</code> indexed by the SAML artifact. + * The <code>AuthenticationData</code> is deleted from the store upon end of + * this call. + * + * @return <code>AuthenticationData</code> + */ + public AuthenticationData getAuthenticationData(String samlArtifact) + throws AuthenticationException { + String assertionHandle; + try { + assertionHandle = new SAMLArtifactParser(samlArtifact) + .parseAssertionHandle(); + } catch (ParseException ex) { + throw new AuthenticationException("1205", new Object[] { + samlArtifact, ex.toString() }); + } + AuthenticationData authData = null; + synchronized (authenticationDataStore) { + // System.out.println("assertionHandle: " + assertionHandle); + authData = (AuthenticationData) authenticationDataStore + .get(assertionHandle); + if (authData == null) { + Logger.error("Assertion not found for SAML Artifact: " + + samlArtifact); + throw new AuthenticationException("1206", + new Object[] { samlArtifact }); + } + boolean keepAssertion = false; + try { + String boolStr = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.KeepAssertion"); + if (null != boolStr && boolStr.equalsIgnoreCase("true")) + keepAssertion = true;// Only allowed for debug purposes!!! + } catch (ConfigurationException ex) { + throw new AuthenticationException("1205", new Object[] { + samlArtifact, ex.toString() }); + } + if (!keepAssertion) { + authenticationDataStore.remove(assertionHandle); + } + } + long now = new Date().getTime(); + if (now - authData.getTimestamp().getTime() > authDataTimeOut) + throw new AuthenticationException("1207", + new Object[] { samlArtifact }); + Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); + return authData; + } + + /** + * Stores authentication data indexed by the assertion handle contained in + * the given saml artifact. + * + * @param samlArtifact + * SAML artifact + * @param authData + * authentication data + * @throws AuthenticationException + * when SAML artifact is invalid + */ + private void storeAuthenticationData(String samlArtifact, + AuthenticationData authData) throws AuthenticationException { + + try { + SAMLArtifactParser parser = new SAMLArtifactParser(samlArtifact); + // check type code 0x0001 + byte[] typeCode = parser.parseTypeCode(); + if (typeCode[0] != 0 || typeCode[1] != 1) + throw new AuthenticationException("auth.06", + new Object[] { samlArtifact }); + String assertionHandle = parser.parseAssertionHandle(); + synchronized (authenticationDataStore) { + Logger.debug("Assertion stored for SAML Artifact: " + + samlArtifact); + authenticationDataStore.put(assertionHandle, authData); + } + } catch (AuthenticationException ex) { + throw ex; + } catch (Throwable ex) { + throw new AuthenticationException("auth.06", + new Object[] { samlArtifact }); + } + } + + /** + * Creates a new session and puts it into the session store. + * + * @param id + * Session ID + * @return AuthenticationSession created + * @exception AuthenticationException + * thrown when an <code>AuthenticationSession</code> is + * running already for the given session ID + */ + private static AuthenticationSession newSession() + throws AuthenticationException { + String sessionID = Random.nextRandom(); + AuthenticationSession newSession = new AuthenticationSession(sessionID); + synchronized (sessionStore) { + AuthenticationSession session = (AuthenticationSession) sessionStore + .get(sessionID); + if (session != null) + throw new AuthenticationException("auth.01", + new Object[] { sessionID }); + sessionStore.put(sessionID, newSession); + } + return newSession; + } + + /** + * Retrieves a session from the session store. + * + * @param id + * session ID + * @return <code>AuthenticationSession</code> stored with given session ID, + * <code>null</code> if session ID unknown + */ + public static AuthenticationSession getSession(String id) + throws AuthenticationException { + AuthenticationSession session = (AuthenticationSession) sessionStore + .get(id); + if (session == null) + throw new AuthenticationException("auth.02", new Object[] { id }); + return session; + } + + /** + * Cleans up expired session and authentication data stores. + */ + public void cleanup() { + long now = new Date().getTime(); + synchronized (sessionStore) { + Set keys = new HashSet(sessionStore.keySet()); + for (Iterator iter = keys.iterator(); iter.hasNext();) { + String sessionID = (String) iter.next(); + AuthenticationSession session = (AuthenticationSession) sessionStore + .get(sessionID); + if (now - session.getTimestampStart().getTime() > sessionTimeOut) { + Logger.info(MOAIDMessageProvider.getInstance().getMessage( + "cleaner.02", new Object[] { sessionID })); + sessionStore.remove(sessionID); + } + } + } + synchronized (authenticationDataStore) { + Set keys = new HashSet(authenticationDataStore.keySet()); + for (Iterator iter = keys.iterator(); iter.hasNext();) { + String samlAssertionHandle = (String) iter.next(); + AuthenticationData authData = (AuthenticationData) authenticationDataStore + .get(samlAssertionHandle); + if (now - authData.getTimestamp().getTime() > authDataTimeOut) { + Logger.info(MOAIDMessageProvider.getInstance().getMessage( + "cleaner.03", + new Object[] { authData.getAssertionID() })); + authenticationDataStore.remove(samlAssertionHandle); + } + } + } + } + + /** + * Sets the sessionTimeOut. + * + * @param seconds + * Time out of the session in seconds + */ + public void setSecondsSessionTimeOut(long seconds) { + sessionTimeOut = 1000 * seconds; + } + + /** + * Sets the authDataTimeOut. + * + * @param seconds + * Time out for signing AuthData in seconds + */ + public void setSecondsAuthDataTimeOut(long seconds) { + authDataTimeOut = 1000 * seconds; + } + + /** + * 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) + */ + private 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; + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java index b7b5bcce6..c719484fa 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java @@ -588,9 +588,9 @@ public class ConfigurationBuilder { oap.setBkuSelectionTemplateURL(buildTemplateURL(authComponent, OA_AUTH_COMPONENT_BKUSELECT_TEMPLATE_XPATH, bkuSelectionTemplateURL)); oap.setTemplateURL(buildTemplateURL(authComponent, OA_AUTH_COMPONENT_TEMPLATE_XPATH, templateURL)); - System.out.println(publicURLPrefix); - System.out.println("useCondition: " + oap.getUseCondition()); - System.out.println("conditionLength: " + oap.getConditionLength()); +// System.out.println(publicURLPrefix); +// System.out.println("useCondition: " + oap.getUseCondition()); +// System.out.println("conditionLength: " + oap.getConditionLength()); oap.setInputProcessorSignTemplateURL(buildTemplateURL(authComponent, INPUT_PROCESSOR_TEMPLATE_XPATH, inputProcessorSignTemplateURL)); // load OA specific transforms if present |