aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java135
1 files changed, 135 insertions, 0 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java
new file mode 100644
index 00000000..4af4e7cf
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java
@@ -0,0 +1,135 @@
+package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.validator;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASValidationException;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.impl.data.Trible;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeValue;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASResponseValidator {
+ private static final Logger log = LoggerFactory.getLogger(eIDASResponseValidator.class);
+
+ public static void validateResponse(IRequest pendingReq, ILightResponse eIDASResponse, String spCountry, eIDASAttributeRegistry attrRegistry) throws eIDASValidationException {
+
+ /*-----------------------------------------------------|
+ * validate received LoA against minimum required LoA |
+ *_____________________________________________________|
+ */
+ LevelOfAssurance respLoA = LevelOfAssurance.fromString(eIDASResponse.getLevelOfAssurance());
+ List<String> allowedLoAs = pendingReq.getServiceProviderConfiguration().getRequiredLoA();
+ boolean loaValid = false;
+ for (String allowedLoaString : allowedLoAs) {
+ LevelOfAssurance allowedLoa = LevelOfAssurance.fromString(allowedLoaString);
+ if (respLoA.numericValue() >= allowedLoa.numericValue()) {
+ log.debug("Response contains valid LoA. Resume process ... ");
+ loaValid = true;
+ break;
+
+ } else
+ log.trace("Allowed LoA: " + allowedLoaString + " DOES NOT match response LoA: " + eIDASResponse.getLevelOfAssurance());
+
+ }
+
+ if (!loaValid) {
+ log.error("eIDAS Response LevelOfAssurance is lower than the required! "
+ + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + allowedLoAs.toArray() + ")");
+ throw new eIDASValidationException("eidas.06", new Object[]{respLoA.getValue()});
+
+ }
+
+
+
+ /*-----------------------------------------------------|
+ * validate 'PersonalIdentifier' attribute |
+ *_____________________________________________________|
+ */
+ AttributeDefinition<?> attrDefinition = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ final ImmutableList<? extends AttributeValue<?>> attributeValues = eIDASResponse.getAttributes().getAttributeMap().get(attrDefinition).asList();
+ List<String> personalIdObj = eIDASResponseUtils.translateStringListAttribute(attrDefinition, attributeValues);
+
+ //check if attribute exists
+ if (personalIdObj == null || personalIdObj.isEmpty()) {
+ log.warn("eIDAS Response include NO 'PersonalIdentifier' attriubte "
+ + ".... That can be a BIG problem in further processing steps");
+ throw new eIDASValidationException("eidas.05", new Object[] {"NO 'PersonalIdentifier' attriubte"});
+
+ } else if (personalIdObj.size() > 1) {
+ log.warn("eIDAS Response include MORE THAN ONE 'PersonalIdentifier' attriubtes "
+ + ".... That can be a BIG problem in further processing steps");
+ throw new eIDASValidationException("eidas.05", new Object[] {"MORE THAN ONE 'PersonalIdentifier' attriubtes"});
+
+ } else {
+ String natPersId = personalIdObj.get(0);
+ //validate attribute value format
+ Trible<String, String, String> split =
+ eIDASResponseUtils.parseEidasPersonalIdentifier(natPersId);
+ if (split == null) {
+ throw new eIDASValidationException("eidas.07",
+ new Object[]{
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ "Wrong identifier format"});
+
+ } else {
+ //validation according to eIDAS SAML Attribute Profile, Section 2.2.3
+ if (StringUtils.isEmpty(split.getSecond())) {
+ log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ + " includes NO destination country. Value:" + natPersId);
+ throw new eIDASValidationException("eidas.07",
+ new Object[]{
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ "No or empty destination country"});
+
+ }
+ if (!split.getSecond().equalsIgnoreCase(spCountry)) {
+ log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ + " includes wrong destination country. Value:" + natPersId
+ + " SP-Country:" + spCountry);
+ throw new eIDASValidationException("eidas.07",
+ new Object[]{
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ "Destination country does not match to SP country"});
+
+ }
+
+ if (StringUtils.isEmpty(split.getFirst())) {
+ log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ + " includes NO citizen country. Value:" + natPersId);
+ throw new eIDASValidationException("eidas.07",
+ new Object[]{
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ "No or empty citizen country"});
+
+ }
+ if (!split.getSecond().equalsIgnoreCase(spCountry)) {
+ log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER
+ + " includes a relaying-party country that does not match to service-provider country. "
+ + " Value:" + natPersId
+ + " SP Country:" + spCountry);
+ throw new eIDASValidationException("eidas.07",
+ new Object[]{
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ "Citizen country does not match to eIDAS-node country that generates the response"});
+
+ }
+ }
+ }
+
+ }
+}