From f681c2e66c4913a37505788b270e70b85ed1111e Mon Sep 17 00:00:00 2001 From: Alexander Marsalek Date: Fri, 12 Feb 2021 11:08:57 +0100 Subject: compare eiddata with mobile phone signature data --- .../eidas/v2/dao/SimpleMobileSignatureData.java | 66 ++++++++++++++++++ ...eSignatureResponseAndSearchInRegistersTask.java | 31 ++++++--- ...natureResponseAndSearchInRegistersTaskTest.java | 78 +++++++++++++++++++++- 3 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java (limited to 'eidas_modules') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java new file mode 100644 index 00000000..254b8c70 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.modules.auth.eidas.v2.dao; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; +import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType; +import lombok.Data; + +@Data +public class SimpleMobileSignatureData { + + private String citizenCountryCode; + + private String bpk; + private String givenName; + private String familyName; + private String dateOfBirth; + + + public boolean equalsSimpleEidasData(SimpleEidasData result) { + if (!result.getGivenName().equals(givenName)) { + return false; + } + if (!result.getFamilyName().equals(familyName)) { + return false; + } + if (!result.getDateOfBirth().equals(dateOfBirth)) { + return false; + } + return true; + } + + private boolean equals(String a, String b) { + if (a == null && b == null) { + return true; + } + if (a == null) { + return false; + } + if (b == null) { + return false; + } + return a.equals(b); + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java index d919d229..101e7c29 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java @@ -27,7 +27,9 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MergedRegisterSearchResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleMobileSignatureData; import at.asitplus.eidas.specific.modules.auth.eidas.v2.ernp.IErnpClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.InvalidUserInputException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ManualFixNecessaryException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.EidasAuthEventConstants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants; @@ -35,6 +37,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustri import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthMetadataProvider; import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.Utils; import at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.IZmrClient; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException; @@ -188,12 +191,16 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends } - // initialize Attribute extractor final AssertionAttributeExtractor extractor = new AssertionAttributeExtractor(processedMsg.getFirst().getResponse()); - String bpkzp = getAuthDataFromInterfederation(extractor, authProcessData); + SimpleMobileSignatureData simpleMobileSignatureData = getAuthDataFromInterfederation(extractor, authProcessData); + if(!simpleMobileSignatureData.equalsSimpleEidasData(eidData)) { + //User cheated? + throw new InvalidUserInputException();//TODO + } + String bpkzp = simpleMobileSignatureData.getBpk(); MergedRegisterSearchResult result = searchInZmrAndErnp(bpkzp); if (result.getResultCount() == 0) { @@ -307,11 +314,12 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends return null; } - private String getAuthDataFromInterfederation(AssertionAttributeExtractor extractor, - AuthProcessDataWrapper authProcessData) + private SimpleMobileSignatureData getAuthDataFromInterfederation(AssertionAttributeExtractor extractor, + AuthProcessDataWrapper authProcessData) throws EaafBuilderException { List requiredAttributes = IdAustriaClientAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES; + SimpleMobileSignatureData simpleMobileSignatureData = new SimpleMobileSignatureData(); String bpk = null; try { // check if all attributes are include @@ -328,13 +336,20 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends map.put(attrName, extractor.getSingleAttributeValue(attrName)); if (PvpAttributeDefinitions.BPK_NAME.equals(attrName)) { - bpk = extractor.getSingleAttributeValue(attrName); + simpleMobileSignatureData.setBpk(extractor.getSingleAttributeValue(attrName)); + } + if (PvpAttributeDefinitions.GIVEN_NAME_NAME.equals(attrName)) { + simpleMobileSignatureData.setGivenName(extractor.getSingleAttributeValue(attrName)); + } + if (PvpAttributeDefinitions.PRINCIPAL_NAME_NAME.equals(attrName)) { + simpleMobileSignatureData.setFamilyName(extractor.getSingleAttributeValue(attrName)); + } + if (PvpAttributeDefinitions.BIRTHDATE_NAME.equals(attrName)) { + simpleMobileSignatureData.setDateOfBirth(extractor.getSingleAttributeValue(attrName)); } if (PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME.equals(attrName)) { authProcessData.setQaaLevel(extractor.getSingleAttributeValue(attrName)); } - //injectAuthInfosIntoSession(session, attrName, - // extractor.getSingleAttributeValue(attrName)); } @@ -370,7 +385,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e); } - return bpk; + return simpleMobileSignatureData; } // private void injectAuthInfosIntoSession(AhAuthProcessDataWrapper session, String attrName, String attrValue) diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java index 2e3da7bc..fbf011b1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java @@ -6,6 +6,10 @@ import java.util.Base64; import javax.xml.transform.TransformerException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MergedRegisterSearchResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.InvalidUserInputException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthCredentialProvider; import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthMetadataProvider; @@ -13,6 +17,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveMobilePhone import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummyAuthConfigMap; import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummyOA; import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummyPendingRequest; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; @@ -520,7 +525,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { @Test public void httpPostValidSignedAssertionEidValid() throws IOException, SamlSigningException, Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, - MarshallingException, TransformerException, TaskExecutionException { + MarshallingException, TransformerException, TaskExecutionException, EaafStorageException { oaParam.putGenericConfigurationKey( IdAustriaClientAuthConstants.CONFIG_PROPS_APPSPECIFIC_EIDAS_NODE_URL, METADATA_PATH); @@ -536,6 +541,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString( DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes("UTF-8"))); + //put SimpleEidasData in session + final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + SimpleEidasData eidData = new SimpleEidasData(); + eidData.setFamilyName("Mustermann"); + eidData.setGivenName("Max"); + eidData.setDateOfBirth("1940-01-01"); + authProcessData.setGenericDataToSession(Constants.DATA_SIMPLE_EIDAS, eidData); + //perform task task.execute(pendingReq, executionContext); @@ -579,10 +592,53 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { ExtendedPvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class)); } + @Test + public void httpPostValidSignedAssertionEidValidButNameMissmatch() throws IOException, SamlSigningException, + Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, + MarshallingException, TransformerException, TaskExecutionException, EaafStorageException { + + oaParam.putGenericConfigurationKey( + IdAustriaClientAuthConstants.CONFIG_PROPS_APPSPECIFIC_EIDAS_NODE_URL, METADATA_PATH); + + metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider( + METADATA_PATH, null, "jUnit IDP", null)); + + final Response response = initializeResponse( + "classpath:/data/idp_metadata_classpath_entity.xml", + "/data/Response_with_EID.xml", + credentialProvider.getMessageSigningCredential(), + true); + httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString( + DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes("UTF-8"))); + + //put SimpleEidasData in session + final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + SimpleEidasData eidData = new SimpleEidasData(); + eidData.setFamilyName("Mustermann1"); + eidData.setGivenName("Max"); + eidData.setDateOfBirth("1940-01-01"); + authProcessData.setGenericDataToSession(Constants.DATA_SIMPLE_EIDAS, eidData); + + //perform task + try { + task.execute(pendingReq, executionContext); + Assert.fail("Invalid response not detected"); + + } catch (final TaskExecutionException e) { + Assert.assertNotNull(e.getPendingRequestID()); + Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); + Assert.assertNotNull(e.getOriginalException()); + org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, + e.getOriginalException()); + Assert.assertTrue(e.getOriginalException().getCause() instanceof InvalidUserInputException); + } + + } + @Test public void httpPostValidSignedAssertionLegacyValid() throws IOException, SamlSigningException, Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, - MarshallingException, TransformerException, TaskExecutionException { + MarshallingException, TransformerException, TaskExecutionException, EaafStorageException { // authConfig.putConfigValue(AuthHandlerConstants.PROP_CONFIG_LEGACY_ALLOW, "true"); oaParam.putGenericConfigurationKey( IdAustriaClientAuthConstants.CONFIG_PROPS_APPSPECIFIC_EIDAS_NODE_URL, METADATA_PATH); @@ -590,6 +646,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider( METADATA_PATH, null, "jUnit IDP", null)); + //put SimpleEidasData in session + final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + SimpleEidasData eidData = new SimpleEidasData(); + eidData.setFamilyName("Mustermann"); + eidData.setGivenName("Max"); + eidData.setDateOfBirth("1940-01-01"); + authProcessData.setGenericDataToSession(Constants.DATA_SIMPLE_EIDAS, eidData); + final Response response = initializeResponse( "classpath:/data/idp_metadata_classpath_entity.xml", "/data/Response_with_legacy.xml", @@ -647,7 +711,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { @Test public void httpPostValidSignedAssertionWithLegacyAndEid() throws IOException, SamlSigningException, Pvp2MetadataException, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, - MarshallingException, TransformerException, TaskExecutionException { + MarshallingException, TransformerException, TaskExecutionException, EaafStorageException { oaParam.putGenericConfigurationKey( IdAustriaClientAuthConstants.CONFIG_PROPS_APPSPECIFIC_EIDAS_NODE_URL, METADATA_PATH); @@ -655,6 +719,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest { metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider( METADATA_PATH, null, "jUnit IDP", null)); + //put SimpleEidasData in session + final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + SimpleEidasData eidData = new SimpleEidasData(); + eidData.setFamilyName("Mustermann"); + eidData.setGivenName("Max"); + eidData.setDateOfBirth("1940-01-01"); + authProcessData.setGenericDataToSession(Constants.DATA_SIMPLE_EIDAS, eidData); + final Response response = initializeResponse( "classpath:/data/idp_metadata_classpath_entity.xml", "/data/Response_with_legacy_and_EID.xml", -- cgit v1.2.3