From 16645606a6e2e6c1b00b2b20ef0373e2c81f7f4a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 8 Feb 2017 14:44:26 +0100 Subject: update eIDAS node configuration to allow more then on configuration for the same country code. Country codes can be extended by a suffix like NL and NL-Test. Both generates a Authn. request for NL but there are two entries in citizen country selector and maybe two different service URLs --- .../validation/moaconfig/StorkConfigValidator.java | 2 +- id/ConfigWebTool/src/main/webapp/css/index.css | 5 +++ .../src/main/webapp/jsp/editMOAConfig.jsp | 4 +-- .../task/impl/GeneralSTORKConfigurationTask.java | 2 +- .../moa/id/config/stork/STORKConfig.java | 4 +-- .../egovernment/moa/id/commons/api/data/CPEPS.java | 12 +++++++ ...roviderSpecificGUIFormBuilderConfiguration.java | 8 ++--- .../eidas/tasks/GenerateAuthnRequestTask.java | 38 ---------------------- 8 files changed, 27 insertions(+), 48 deletions(-) diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/moaconfig/StorkConfigValidator.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/moaconfig/StorkConfigValidator.java index ed2c2f903..8e8020d75 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/moaconfig/StorkConfigValidator.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/moaconfig/StorkConfigValidator.java @@ -43,7 +43,7 @@ public class StorkConfigValidator { errors.add(LanguageHelper.getErrorString("validation.stork.cpeps.cc", new Object[] {ValidationHelper.getPotentialCSSCharacter(false)}, request )); } - if(!check.toLowerCase().matches("^[a-z][a-z]$")) { + if(!check.toLowerCase().matches("(^[a-z][a-z]$)|(^[a-z][a-z]-[a-z]*)")) { log.warn("CPEPS config countrycode does not comply to ISO 3166-2 : " + check); errors.add(LanguageHelper.getErrorString("validation.stork.cpeps.cc", new Object[] {check}, request )); diff --git a/id/ConfigWebTool/src/main/webapp/css/index.css b/id/ConfigWebTool/src/main/webapp/css/index.css index 80ccf93be..aa83e0c2b 100644 --- a/id/ConfigWebTool/src/main/webapp/css/index.css +++ b/id/ConfigWebTool/src/main/webapp/css/index.css @@ -375,6 +375,11 @@ div .wwgrp br { } +.textfield_PEPS_CC { + width: 70px; + +} + .textfield_middle { width: 100px; diff --git a/id/ConfigWebTool/src/main/webapp/jsp/editMOAConfig.jsp b/id/ConfigWebTool/src/main/webapp/jsp/editMOAConfig.jsp index 6694a4273..6892535a1 100644 --- a/id/ConfigWebTool/src/main/webapp/jsp/editMOAConfig.jsp +++ b/id/ConfigWebTool/src/main/webapp/jsp/editMOAConfig.jsp @@ -296,7 +296,7 @@ - + @@ -307,7 +307,7 @@ - + " onclick='this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);'/> diff --git a/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/GeneralSTORKConfigurationTask.java b/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/GeneralSTORKConfigurationTask.java index 6d1dafd6c..fb675ad43 100644 --- a/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/GeneralSTORKConfigurationTask.java +++ b/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/GeneralSTORKConfigurationTask.java @@ -125,7 +125,7 @@ public static final List KEYWHITELIST; LanguageHelper.getErrorString("validation.stork.cpeps.cc", new Object[] {ValidationHelper.getPotentialCSSCharacter(false)}))); } - if(!cc.toLowerCase().matches("^[a-z][a-z]$")) { + if(!cc.toLowerCase().matches("(^[a-z][a-z]$)|(^[a-z][a-z]-[a-z]*)")) { log.warn("CPEPS config countrycode does not comply to ISO 3166-2 : " + cc); errors.add(new ValidationObjectIdentifier( MOAIDConfigurationConstants.GENERAL_AUTH_STORK_CPEPS_LIST diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java index 99e4b4cce..b85938bb7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java @@ -96,7 +96,7 @@ public class STORKConfig implements IStorkConfig { new CPEPS(storkCPEPSProps.get(listCounter + "." + MOAIDConfigurationConstants.GENERAL_AUTH_STORK_CPEPS_LIST_COUNTRY), new URL(storkCPEPSProps.get(listCounter + "." + MOAIDConfigurationConstants.GENERAL_AUTH_STORK_CPEPS_LIST_URL)), enableAssertionEncryption); - cpepsMap.put(moacpep.getCountryCode(), moacpep); + cpepsMap.put(moacpep.getFullCountryCode(), moacpep); } catch (MalformedURLException e) { Logger.warn("CPEPS URL " + @@ -167,7 +167,7 @@ public class STORKConfig implements IStorkConfig { if (StringUtils.isEmpty(ccc) || this.cpepsMap.isEmpty()) return false; - if (this.cpepsMap.containsKey(ccc.toUpperCase())) + if (this.cpepsMap.containsKey(ccc)) return true; else return false; diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/data/CPEPS.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/data/CPEPS.java index a88aa2171..525a660b4 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/data/CPEPS.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/data/CPEPS.java @@ -62,11 +62,23 @@ public class CPEPS { this.isXMLSignatureSupported = isXMLSignatureSupported; } + + public String getFullCountryCode() { + return countryCode; + } + /** * Gets the country code of this C-PEPS * @return ISO country code */ public String getCountryCode() { + if (countryCode != null && + countryCode.contains("-")) { + //remove trailing information to country code + return countryCode.substring(0, countryCode.indexOf("-")); + + } + return countryCode; } diff --git a/id/server/moa-id-frontend-resources/src/main/java/at/gv/egovernment/moa/id/auth/frontend/builder/ServiceProviderSpecificGUIFormBuilderConfiguration.java b/id/server/moa-id-frontend-resources/src/main/java/at/gv/egovernment/moa/id/auth/frontend/builder/ServiceProviderSpecificGUIFormBuilderConfiguration.java index 0a5cdaf3e..63df81b3c 100644 --- a/id/server/moa-id-frontend-resources/src/main/java/at/gv/egovernment/moa/id/auth/frontend/builder/ServiceProviderSpecificGUIFormBuilderConfiguration.java +++ b/id/server/moa-id-frontend-resources/src/main/java/at/gv/egovernment/moa/id/auth/frontend/builder/ServiceProviderSpecificGUIFormBuilderConfiguration.java @@ -126,12 +126,12 @@ public class ServiceProviderSpecificGUIFormBuilderConfiguration extends Abstract try { for (CPEPS current : oaParam.getPepsList()) { String countryName = null; - if (MiscUtil.isNotEmpty(MOAIDAuthConstants.COUNTRYCODE_XX_TO_NAME.get(current.getCountryCode().toUpperCase()))) - countryName = MOAIDAuthConstants.COUNTRYCODE_XX_TO_NAME.get(current.getCountryCode().toUpperCase()); + if (MiscUtil.isNotEmpty(MOAIDAuthConstants.COUNTRYCODE_XX_TO_NAME.get(current.getFullCountryCode().toUpperCase()))) + countryName = MOAIDAuthConstants.COUNTRYCODE_XX_TO_NAME.get(current.getFullCountryCode().toUpperCase()); else - countryName = current.getCountryCode().toUpperCase(); + countryName = current.getFullCountryCode().toUpperCase(); - pepslist += "\n"; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java index 0eb067c5a..7f3c97dc6 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -22,13 +22,10 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; -import java.io.ByteArrayOutputStream; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -42,7 +39,6 @@ import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.saml2.metadata.provider.MetadataProviderException; -import org.opensaml.xml.util.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -274,40 +270,6 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { } } - - /** - * Encode the eIDAS request with Redirect binding - * - * @param pendingReq - * @param authnReqEndpoint - * @param token - * @param authnRequest - * @param response - * @throws MOAIDException - */ - private void buildRedirecttBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint, - byte[] token, IRequestMessage authnRequest, HttpServletResponse response) - throws MOAIDException { - - //FIXME: implement correct deflat encoding accodring to SAML2 Redirect Binding specification - - try { - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - Deflater deflater = new Deflater(Deflater.DEFLATED, true); - DeflaterOutputStream deflaterStream = new DeflaterOutputStream(bytesOut, deflater); - deflaterStream.write(token); - deflaterStream.finish(); - String samlReqBase64 = Base64.encodeBytes(bytesOut.toByteArray(), Base64.DONT_BREAK_LINES); - - - - } catch (Exception e) { - Logger.error("eIDAS Redirect-Binding request encoding error: " + e.getMessage()); - throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); - - } - - } /** * Encode the eIDAS request with POST binding -- cgit v1.2.3 From be8d392611fe2ed733869a4a9701904313a207fd Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 8 Feb 2017 15:59:45 +0100 Subject: update eIDAS assertion generation to generate an error message if attribute that is marked as required is not available --- .../resources/resources/properties/id_messages_de.properties | 1 + .../properties/protocol_response_statuscodes_de.properties | 1 + .../moa/id/protocols/eidas/eIDASAuthenticationRequest.java | 10 ++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index b88df0b9d..79dc11f34 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -271,6 +271,7 @@ eIDAS.11=Received eIDAS Error-Response. Reason:{0} eIDAS.12=Received eIDAS AuthnRequest is not valid. Reason:{0} eIDAS.13=Generation of eIDAS Response FAILED. Reason:{0} eIDAS.14=eIDAS Response validation FAILED: LevelOfAssurance {0} is to low. +eIDAS.15=Generation of eIDAS Response FAILED. Required attribute: {0} is NOT available. pvp2.01=Fehler beim kodieren der PVP2 Antwort pvp2.02=Ungueltiges Datumsformat diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties index e72a28046..8d6c77831 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties @@ -228,6 +228,7 @@ eIDAS.11=1302 eIDAS.12=1305 eIDAS.13=1307 eIDAS.14=1301 +eIDAS.15=1307 pvp2.01=6100 pvp2.06=6100 diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index 97241af6a..f0e7e918b 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -145,8 +145,14 @@ public class eIDASAuthenticationRequest implements IAction { } - if(MiscUtil.isEmpty(newValue)) { - Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available."); + if(MiscUtil.isEmpty(newValue)) { + if (attr.isRequired()) { + Logger.info("eIDAS Attr:" + attr.getNameUri() + " is marked as 'Required' but not available."); + throw new MOAIDException("eIDAS.15", new Object[]{attr.getFriendlyName()}); + + } else + Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available."); + } else { //set uniqueIdentifier attribute, because eIDAS SAMLEngine use this flag to select the -- cgit v1.2.3 From 9c74bf7357a11c7a173ed2468c34164d07ee7a5a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 8 Feb 2017 16:55:34 +0100 Subject: fix bug in configuration tool during eIDAS LoA level load operation --- .../moa/id/commons/config/ConfigurationMigrationUtils.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java index 61b08f3a6..b8284c8f9 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java @@ -981,13 +981,17 @@ public class ConfigurationMigrationUtils { } // transfer the incoming data to the database model stork.setStorkLogonEnabled(Boolean.parseBoolean(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_ENABLED))); - if (MiscUtil.isNotEmpty(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL))) + if (MiscUtil.isNotEmpty(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL))) { try { + stork.seteIDAS_LOA(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL)); stork.setQaa(Integer.valueOf(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL))); + } catch (NumberFormatException e) { Logger.info("Downgraded OA config found -> change eIDAS LoA to STORK QAA"); stork.setQaa(4); + } + } if (MiscUtil.isNotEmpty(oa.get(MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES)) && oa.get(MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES).equals(MOAIDConfigurationConstants.PREFIX_VIDP)) -- cgit v1.2.3 From a2caf29a1bf69140ef97bc738875fdbad97bf8a2 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 8 Feb 2017 16:56:42 +0100 Subject: if OA requests no eIDAS attributes than request PersonalIdentifier as minimum --- .../auth/modules/eidas/tasks/GenerateAuthnRequestTask.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java index 7f3c97dc6..7155040c6 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -193,7 +193,17 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { } } - //build requested attribute set + //request + if (reqAttrList.isEmpty()) { + Logger.info("No attributes requested by OA:" + pendingReq.getOnlineApplicationConfiguration().getPublicURLPrefix() + + " --> Request attr:" + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + " by default"); + AttributeDefinition newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); + Builder attrBuilder = AttributeDefinition.builder(newAttribute).required(true); + reqAttrList.add(attrBuilder.build()); + + } + + //build requested attribute set ImmutableAttributeMap reqAttrMap = new ImmutableAttributeMap.Builder().putAll(reqAttrList).build(); //build eIDAS AuthnRequest -- cgit v1.2.3 From d6f9f64e29d986df48f3c7d8a1bb9df4cb5f7095 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 8 Feb 2017 16:57:45 +0100 Subject: add additional validation of eIDAS country target for bPK calculation --- .../id/configuration/validation/oa/OATargetConfigValidation.java | 9 +++++++++ .../src/main/resources/applicationResources_de.properties | 1 + .../src/main/resources/applicationResources_en.properties | 1 + 3 files changed, 11 insertions(+) diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java index 650553ab3..9cb3ce700 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java @@ -74,6 +74,15 @@ public class OATargetConfigValidation { log.info("Not valid CompanyNumber"); errors.add(LanguageHelper.getErrorString("validation.general.identificationnumber.fn.valid", request)); } + + } else if (form.getIdentificationType().equals(Constants.IDENIFICATIONTYPE_EIDAS)) { + String[] test = check.split("\\+"); + if (test.length < 2) { + log.info("Not valid eIDAS Target"); + errors.add(LanguageHelper.getErrorString("validation.general.identificationnumber.eidas.valid", request)); + + } + } } diff --git a/id/ConfigWebTool/src/main/resources/applicationResources_de.properties b/id/ConfigWebTool/src/main/resources/applicationResources_de.properties index fe1dac063..d75403575 100644 --- a/id/ConfigWebTool/src/main/resources/applicationResources_de.properties +++ b/id/ConfigWebTool/src/main/resources/applicationResources_de.properties @@ -480,6 +480,7 @@ validation.general.identificationtype.valid=Der Identifikationstype wird nicht u validation.general.identificationnumber.empty=Im privatwirtschaftlichen Bereich ist eine Identifikationsnummer erforderlich. validation.general.identificationnumber.valid=Die Identifikationsnummer f\u00FCr den privatwirtschaftlichen Bereich enth\u00E4lt nicht erlaubte Zeichen. Folgende Zeichen sind nicht erlaubt\: {0} validation.general.identificationnumber.fn.valid=Die Firmenbuchnummer hat kein g\u00FCltiges Format. +validation.general.identificationnumber.eidas.valid=Der eIDAS-Node Target hat kein g\u00FCltiges Format. (z.B. AT+NL) validation.general.oaidentifier.empty=Es wurde kein eindeutiger Identifier f\u00FCr die Online-Applikation angegeben. validation.general.oaidentifier.valid=Der eindeutige Identifier f\u00FCr die Online-Applikation ist keine g\u00FCltige URL. validation.general.oaidentifier.notunique=Der gew\u00E4hlte eindeutige Identifier ist bereits vorhanden (kollision mit {0}). Eine Eintragung der Online-Applikation ist nicht m\u00F6glich. diff --git a/id/ConfigWebTool/src/main/resources/applicationResources_en.properties b/id/ConfigWebTool/src/main/resources/applicationResources_en.properties index 126bba7c9..708cc605e 100644 --- a/id/ConfigWebTool/src/main/resources/applicationResources_en.properties +++ b/id/ConfigWebTool/src/main/resources/applicationResources_en.properties @@ -478,6 +478,7 @@ validation.general.identificationtype.valid=The identification type is not suppo validation.general.identificationnumber.empty=The identification number is necessary for private sector. validation.general.identificationnumber.valid=The identification number for the private sector contains forbidden characters. The following characters are not allowed\: {0} validation.general.identificationnumber.fn.valid=The identification number has invalid format. +validation.general.identificationnumber.eidas.valid=The eIDAS-node identification number has invalid format. (e.g. AT+NL) validation.general.oaidentifier.empty=There is no unique identifier for the Online-Application provided. validation.general.oaidentifier.valid=The unique identifier for the Online-Application is not valid URL. validation.general.oaidentifier.notunique=The selected unique identifier is already available (collision with {0}). Registration of the Online-Application was not possible. -- cgit v1.2.3 From a90e70cf7beb2fe596185309b0e9c305af08c045 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 9 Feb 2017 15:33:11 +0100 Subject: update eIDAS node target validator --- .../id/configuration/validation/oa/OATargetConfigValidation.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java index 9cb3ce700..0062beb96 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/validation/oa/OATargetConfigValidation.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.configuration.validation.oa; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; @@ -76,8 +78,9 @@ public class OATargetConfigValidation { } } else if (form.getIdentificationType().equals(Constants.IDENIFICATIONTYPE_EIDAS)) { - String[] test = check.split("\\+"); - if (test.length < 2) { + Pattern pattern = Pattern.compile("[A-Z,a-z]{2}\\+[A-Z,a-z]{2}"); + Matcher matcher = pattern.matcher(check); + if (!matcher.matches()) { log.info("Not valid eIDAS Target"); errors.add(LanguageHelper.getErrorString("validation.general.identificationnumber.eidas.valid", request)); -- cgit v1.2.3 From dd88bbb1a644575395a03dcd757c0e3174914724 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 9 Feb 2017 15:34:02 +0100 Subject: fix bug in bPK builder for eIDAS targets --- .../src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java index 9e4e36fec..32ac8ad68 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java @@ -238,7 +238,7 @@ public class BPKBuilder { Logger.debug("Building eIDAS identification from: " + sourceCountry+"/"+destinationCountry+"/" + "[identValue]"); String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bPK; - return Pair.newInstance(eIdentifier, baseIDType); + return Pair.newInstance(eIdentifier, bPKType); } private String calculatebPKwbPK(String basisbegriff) throws BuildException { -- cgit v1.2.3 From 3d6692ef16835b4ceeae3d3e85ea3bce053ab1a4 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 9 Feb 2017 15:35:15 +0100 Subject: add additional validation steps in eIDAS message processing --- .../id/auth/builder/AuthenticationDataBuilder.java | 25 ++-- .../gv/egovernment/moa/id/moduls/RequestImpl.java | 2 +- .../resources/properties/id_messages_de.properties | 1 + .../protocol_response_statuscodes_de.properties | 1 + .../java/at/gv/egovernment/moa/util/Constants.java | 2 +- .../eidas/tasks/ReceiveAuthnResponseTask.java | 14 +-- .../eidas/utils/eIDASAttributeProcessingUtils.java | 75 ++++++++++++ .../moa/id/protocols/eidas/EIDASProtocol.java | 44 +++++-- .../eidas/eIDASAuthenticationRequest.java | 34 +++++- .../eidas/validator/eIDASResponseValidator.java | 130 +++++++++++++++++++++ 10 files changed, 290 insertions(+), 38 deletions(-) create mode 100644 id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeProcessingUtils.java create mode 100644 id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/validator/eIDASResponseValidator.java diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index 3264fc3bd..cad3354f5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -71,7 +71,6 @@ import at.gv.egovernment.moa.id.data.AuthenticationRoleFactory; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.data.Pair; -import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; @@ -1105,16 +1104,20 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { String baseID = authData.getIdentificationValue(); String baseIDType = authData.getIdentificationType(); - - String eIDASOutboundCountry = pendingReq.getGenericData(RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, String.class); - - //TODO: maybe find a better solution - String cititzenCountryCode = - authConfig.getBasicMOAIDConfiguration("moa.id.protocols.eIDAS.node.countrycode", - MOAIDAuthConstants.COUNTRYCODE_AUSTRIA); - - if (Constants.URN_PREFIX_BASEID.equals(baseIDType)) { - if (MiscUtil.isNotEmpty(eIDASOutboundCountry) && !cititzenCountryCode.equals(eIDASOutboundCountry)) { + + if (Constants.URN_PREFIX_BASEID.equals(baseIDType)) { + //Calculate eIDAS identifier + if (oaParam.getBusinessService() && + oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_EIDAS)) { + String[] splittedTarget = oaParam.getIdentityLinkDomainIdentifier().split("\\+"); + String cititzenCountryCode = splittedTarget[1]; + String eIDASOutboundCountry = splittedTarget[2]; + + if (cititzenCountryCode.equalsIgnoreCase(eIDASOutboundCountry)) { + Logger.warn("Suspect configuration FOUND!!! CitizenCountry equals DestinationCountry"); + + } + Pair eIDASID = new BPKBuilder().buildeIDASIdentifer(baseIDType, baseID, cititzenCountryCode, eIDASOutboundCountry); Logger.debug("Authenticate user with bPK:" + eIDASID.getFirst() + " Type:" + eIDASID.getSecond()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java index b612352c6..b87574d52 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java @@ -61,7 +61,7 @@ public abstract class RequestImpl implements IRequest, Serializable{ public static final String DATAID_REQUESTER_IP_ADDRESS = "requesterIP"; - public static final String eIDAS_GENERIC_REQ_DATA_COUNTRY = "country"; +// public static final String eIDAS_GENERIC_REQ_DATA_COUNTRY = "country"; public static final String eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE = "eIDAS_LoA"; diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 79dc11f34..1a2f0d1d3 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -272,6 +272,7 @@ eIDAS.12=Received eIDAS AuthnRequest is not valid. Reason:{0} eIDAS.13=Generation of eIDAS Response FAILED. Reason:{0} eIDAS.14=eIDAS Response validation FAILED: LevelOfAssurance {0} is to low. eIDAS.15=Generation of eIDAS Response FAILED. Required attribute: {0} is NOT available. +eIDAS.16=eIDAS Response attribute-validation FAILED. Attribute:{0} Reason: {1}. pvp2.01=Fehler beim kodieren der PVP2 Antwort pvp2.02=Ungueltiges Datumsformat diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties index 8d6c77831..c6d0844ce 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties @@ -229,6 +229,7 @@ eIDAS.12=1305 eIDAS.13=1307 eIDAS.14=1301 eIDAS.15=1307 +eIDAS.16=1301 pvp2.01=6100 pvp2.06=6100 diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java index 260b2ecb1..129478270 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java @@ -449,7 +449,7 @@ public interface Constants { //TODO: update to eIDAS prefix /** URN prefix for context dependent id (eIDAS). */ - public static final String URN_PREFIX_EIDAS = URN_PREFIX + ":storkid"; + public static final String URN_PREFIX_EIDAS = URN_PREFIX + ":eidasid"; /** URN prefix for context dependent id. */ public static final String URN_PREFIX_BASEID = URN_PREFIX + ":baseid"; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java index c4b2bfeae..45ba3d64e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java @@ -19,12 +19,12 @@ import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.eidas.validator.eIDASResponseValidator; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.eidas.auth.commons.EidasStringUtil; import eu.eidas.auth.commons.protocol.IAuthenticationResponse; -import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; import eu.eidas.auth.engine.ProtocolEngineI; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; @@ -78,16 +78,8 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { // ********************************************************** // ******* MOA-ID specific response validation ********** // ********************************************************** - - //validate received LoA against minimum required LoA - LevelOfAssurance reqLoA = LevelOfAssurance.fromString(pendingReq.getOnlineApplicationConfiguration().getQaaLevel()); - LevelOfAssurance respLoA = LevelOfAssurance.fromString(samlResp.getLevelOfAssurance()); - if (respLoA.numericValue() < reqLoA.numericValue()) { - Logger.error("eIDAS Response LevelOfAssurance is lower than the required! " - + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + reqLoA.getValue() + ")"); - throw new MOAIDException("eIDAS.14", new Object[]{respLoA.getValue()}); - - } + String spCountry = authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"); + eIDASResponseValidator.validateResponse(pendingReq, samlResp, spCountry); // ********************************************************** diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeProcessingUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeProcessingUtils.java new file mode 100644 index 000000000..30e1e4505 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeProcessingUtils.java @@ -0,0 +1,75 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.data.Trible; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class eIDASAttributeProcessingUtils { + public static final String PERSONALIDENIFIER_VALIDATION_PATTERN = "^[A-Z,a-z]{2}/[A-Z,a-z]{2}/.*"; + + /** + * Validate a eIDAS PersonalIdentifier attribute value + * This validation is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier + * + * @param uniqueID eIDAS attribute value of a unique identifier + * @return true if the uniqueID matches to eIDAS to Unique Identifier specification, otherwise false + */ + public static boolean validateEidasPersonalIdentifier(String uniqueID) { + Pattern pattern = Pattern.compile(PERSONALIDENIFIER_VALIDATION_PATTERN ); + Matcher matcher = pattern.matcher(uniqueID); + return matcher.matches(); + + } + + + /** + * Parse an eIDAS PersonalIdentifier attribute value into it components. + * This processing is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier + * + * @param uniqueID eIDAS attribute value of a unique identifier + * @return {@link Trible} that contains: + *
First : citizen country + *
Second: destination country + *
Third : unique identifier + *
or null if the attribute value has a wrong format + */ + public static Trible parseEidasPersonalIdentifier(String uniqueID) { + if (!validateEidasPersonalIdentifier(uniqueID)) { + Logger.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " looks wrong formated. Value:" + ((String)uniqueID)); + return null; + + } + return Trible.newInstance(uniqueID.substring(0, 2), uniqueID.substring(3, 5), uniqueID.substring(6)); + + } +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java index aefae939b..589cd9654 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -25,6 +25,8 @@ package at.gv.egovernment.moa.id.protocols.eidas; import java.io.IOException; import java.io.StringWriter; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -213,6 +215,11 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { } + //check eIDAS node configuration + IOAAuthParameters oaConfig = authConfig.getOnlineApplicationParameter(samlReq.getIssuer()); + if (oaConfig == null) + throw new EIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{samlReq.getIssuer()}); + //validate AssertionConsumerServiceURL against metadata EntityDescriptor eIDASNodeEntityDesc = new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider) .getEntityDescriptor(eIDASSamlReq.getIssuer(), SAMLEngineUtils.getMetadataSigner()); @@ -258,8 +265,33 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { } + //validate request country-code against eIDAS node config + String reqCC = samlReq.getOriginCountryCode(); + String eIDASTarget = oaConfig.getIdentityLinkDomainIdentifier(); + + //validate eIDAS target + Pattern pattern = Pattern.compile("^" + at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS + + "\\+[A-Z,a-z]{2}\\+[A-Z,a-z]{2}$"); + Matcher matcher = pattern.matcher(eIDASTarget); + if (MiscUtil.isEmpty(eIDASTarget) || !matcher.matches()) { + Logger.error("Configuration for eIDAS-node:" + samlReq.getIssuer() + + " contains wrong formated eIDAS target:" + eIDASTarget); + throw new MOAIDException("config.08", new Object[]{samlReq.getIssuer()}); + + } else { + String[] splittedTarget = eIDASTarget.split("\\+"); + if (!splittedTarget[2].equalsIgnoreCase(reqCC)) { + Logger.error("Configuration for eIDAS-node:" + samlReq.getIssuer() + + " Destination Country from request (" + reqCC + + ") does not match to configuration:" + eIDASTarget); + throw new MOAIDException("eIDAS.01", + new Object[]{"Destination Country from request does not match to configuration"}); + + } + Logger.debug("CountryCode from request matches eIDAS-node configuration target"); + } - + //************************************************* //***** store eIDAS request information ********* //************************************************* @@ -269,10 +301,6 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { // - memorize relaystate String relayState = request.getParameter("RelayState"); pendingReq.setRemoteRelayState(relayState); - - // - memorize country code of target country - pendingReq.setGenericDataToSession( - RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getOriginCountryCode()); //store level of assurance pendingReq.setGenericDataToSession(RequestImpl.eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE, @@ -288,10 +316,6 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { pendingReq.setOAURL(samlReq.getIssuer()); // - memorize OA config - IOAAuthParameters oaConfig = authConfig.getOnlineApplicationParameter(pendingReq.getOAURL()); - if (oaConfig == null) - throw new EIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()}); - pendingReq.setOnlineApplicationConfiguration(oaConfig); // - memorize service-provider type from eIDAS request @@ -302,7 +326,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { if (MiscUtil.isEmpty(spType)) spType = MetadataUtil.getSPTypeFromMetadata(eIDASNodeEntityDesc); - if (MiscUtil.isEmpty(spType)) + if (MiscUtil.isNotEmpty(spType)) Logger.debug("eIDAS request has SPType:" + spType); else Logger.info("eIDAS request and eIDAS metadata contains NO 'SPType' element."); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index f0e7e918b..26a171ba8 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -43,12 +43,14 @@ import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SimpleEidasAttributeGenerator; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.eIDASAttributeProcessingUtils; import at.gv.egovernment.moa.id.commons.MOAIDConstants; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationImpl; import at.gv.egovernment.moa.id.data.SLOInformationInterface; +import at.gv.egovernment.moa.id.data.Trible; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator; import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonFullNameAttributeBuilder; @@ -121,12 +123,28 @@ public class eIDASAuthenticationRequest implements IAction { newValue = authData.getBPK(); isUniqueID = true; + //generate eIDAS conform 'PersonalIdentifier' attribute + if (!eIDASAttributeProcessingUtils.validateEidasPersonalIdentifier(newValue)) { + Logger.debug("preCalculated PersonalIdentifier does not include eIDAS conform prefixes ... add prefix now"); + if (MiscUtil.isEmpty(authData.getBPKType()) + || !authData.getBPKType().startsWith(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS)) { + Logger.error("BPKType is empty or does not start with eIDAS bPKType prefix! bPKType:" + authData.getBPKType()); + throw new MOAIDException("builder.08", new Object[]{"Suspect bPKType for eIDAS identifier generation"}); + + } + + String prefix = authData.getBPKType().substring(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS.length() + 1); + newValue = prefix.replaceAll("\\+", "/") + "/" + newValue; + + } + //generate a transient unique identifier if it is requested String reqNameIDFormat = eidasRequest.getEidasRequest().getNameIdFormat(); if (MiscUtil.isNotEmpty(reqNameIDFormat) && reqNameIDFormat.equals(SamlNameIdFormat.TRANSIENT.getNameIdFormat())) newValue = generateTransientNameID(newValue); - + + subjectNameID = newValue; break; case Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER: @@ -301,12 +319,20 @@ public class eIDASAuthenticationRequest implements IAction { private String generateTransientNameID(String nameID) { - String random = Random.nextLongRandom(); + //extract source-country and destination country from persistent identifier + Trible split = eIDASAttributeProcessingUtils.parseEidasPersonalIdentifier(nameID); + if (split == null) { + Logger.error("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!"); + throw new IllegalStateException("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!"); + + } + //build correct formated transient identifier + String random = Random.nextLongRandom(); try { MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1")); - return Base64Utils.encode(hash); + byte[] hash = md.digest((split.getThird() + random).getBytes("ISO-8859-1")); + return split.getFirst() + "/" + split.getSecond() + "/" + Base64Utils.encode(hash); } catch (Exception e) { Logger.error("Can not generate transient personal identifier!", e); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/validator/eIDASResponseValidator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/validator/eIDASResponseValidator.java new file mode 100644 index 000000000..f0527bc5e --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/validator/eIDASResponseValidator.java @@ -0,0 +1,130 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.protocols.eidas.validator; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.eIDASAttributeProcessingUtils; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.data.Trible; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.commons.protocol.IAuthenticationResponse; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; + +/** + * @author tlenz + * + */ +public class eIDASResponseValidator { + + + public static void validateResponse(IRequest pendingReq, IAuthenticationResponse samlResp, String spCountry) throws MOAIDException { + + /*-----------------------------------------------------| + * validate received LoA against minimum required LoA | + *_____________________________________________________| + */ + LevelOfAssurance reqLoA = LevelOfAssurance.fromString(pendingReq.getOnlineApplicationConfiguration().getQaaLevel()); + LevelOfAssurance respLoA = LevelOfAssurance.fromString(samlResp.getLevelOfAssurance()); + if (respLoA.numericValue() < reqLoA.numericValue()) { + Logger.error("eIDAS Response LevelOfAssurance is lower than the required! " + + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + reqLoA.getValue() + ")"); + throw new MOAIDException("eIDAS.14", new Object[]{respLoA.getValue()}); + + } + + /*-----------------------------------------------------| + * validate 'PersonalIdentifier' attribute | + *_____________________________________________________| + */ + String respCC = samlResp.getCountry(); + Object personalIdObj = samlResp.getAttributes().getFirstValue( + SAMLEngineUtils.getMapOfAllAvailableAttributes().get( + Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); + + //check attribute type + if (personalIdObj == null || !(personalIdObj instanceof String)) + Logger.warn("eIDAS Response include NO 'PersonalIdentifier' attriubte " + + ".... That can be a BIG problem in further processing steps"); + + else { + //validate attribute value format + Trible split = + eIDASAttributeProcessingUtils.parseEidasPersonalIdentifier((String)personalIdObj); + if (split == null) { + throw new MOAIDException("eIDAS.16", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Wrong identifier format"}); + + } else { + //validation according to eIDAS SAML Attribute Profile, Section 2.2.3 + if (MiscUtil.isEmpty(split.getSecond())) { + Logger.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO destination country. Value:" + ((String)personalIdObj)); + throw new MOAIDException("eIDAS.16", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty destination country"}); + + } + if (!split.getSecond().equalsIgnoreCase(spCountry)) { + Logger.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes wrong destination country. Value:" + ((String)personalIdObj) + + " SP-Country:" + spCountry); + throw new MOAIDException("eIDAS.16", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Destination country does not match to SP country"}); + + } + + if (MiscUtil.isEmpty(split.getFirst())) { + Logger.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO citizen country. Value:" + ((String)personalIdObj)); + throw new MOAIDException("eIDAS.16", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty citizen country"}); + + } + if (!split.getFirst().equalsIgnoreCase(respCC)) { + Logger.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes a citizen country that does not match to eIDAS Response node. " + + " Value:" + ((String)personalIdObj) + + " Response-Node Country:" + respCC); + throw new MOAIDException("eIDAS.16", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Citizen country does not match to eIDAS-node country that generates the response"}); + + } + } + } + + + + } +} -- cgit v1.2.3 From cb57226d20f61b33e485144f2814edcd36589d5e Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 10 Feb 2017 08:30:01 +0100 Subject: update eIDAS specific revisionslog entries --- id/server/doc/handbook/additional/additional.html | 15 +++++++++++++++ .../egovernment/moa/id/auth/modules/eidas/Constants.java | 2 -- .../egovernment/moa/id/protocols/eidas/EIDASProtocol.java | 3 ++- .../id/protocols/eidas/eIDASAuthenticationRequest.java | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/id/server/doc/handbook/additional/additional.html b/id/server/doc/handbook/additional/additional.html index ec57a74c6..9e3cdf11e 100644 --- a/id/server/doc/handbook/additional/additional.html +++ b/id/server/doc/handbook/additional/additional.html @@ -360,6 +360,21 @@

 

SAML1 StartAuthentication Request

+ + 3400 +   + eIDAS Metadata Request + + + 3401 + Request ID + Eingehender eIDAS Authentication Request + + + 3402 + Response ID + eIDAS Authentication Response erstellt +

4000

 

diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java index 6cb4d6add..369d77863 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java @@ -98,8 +98,6 @@ public class Constants { public static final int eIDAS_REVERSIONSLOG_METADATA = 3400; public static final int eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST = 3401; public static final int eIDAS_REVERSIONSLOG_IDP_AUTHRESPONSE = 3402; - public static final int eIDAS_REVERSIONSLOG_SP_AUTHREQUEST= 3403; - public static final int eIDAS_REVERSIONSLOG_SP_AUTHRESPONSE= 3404; //metadata constants // public final static Map METADATA_POSSIBLE_ATTRIBUTES = Collections.unmodifiableMap( diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java index 589cd9654..388d65963 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -151,7 +151,8 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { //preProcess eIDAS request preProcess(req, resp, pendingReq); - revisionsLogger.logEvent(pendingReq, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST); + revisionsLogger.logEvent(pendingReq, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST, + pendingReq.getEidasRequest().getId()); //AuthnRequest needs authentication pendingReq.setNeedAuthentication(true); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index 26a171ba8..2fe52bb4f 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -252,7 +252,8 @@ public class eIDASAuthenticationRequest implements IAction { } - revisionsLogger.logEvent(req, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST); + revisionsLogger.logEvent(req, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHRESPONSE, + eIDASRespMsg.getResponse().getId()); // send the response try { -- cgit v1.2.3