From 440dcedcfb17e05e439d3019a8cfdb27c307123d Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 17 Mar 2022 08:17:14 +0100 Subject: test(core): fix integration test with included work-around for IDA mode --- .../connector/test/FullStartUpAndProcessTest.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'connector/src') diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java index 64e8272e..c56ac1ef 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java @@ -11,6 +11,9 @@ import java.net.URISyntaxException; import java.util.Map; import java.util.Timer; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; import javax.xml.transform.TransformerException; import org.apache.commons.lang3.RandomStringUtils; @@ -85,7 +88,10 @@ import eu.eidas.specificcommunication.protocol.SpecificCommunicationService; import lombok.val; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.xml.XMLParserException; +import szrservices.GetIdentityLinkEidasResponse; +import szrservices.PersonInfoType; import szrservices.SZR; +import szrservices.SZRException_Exception; import szrservices.SignContentEntry; import szrservices.SignContentResponseType; @@ -400,6 +406,8 @@ public class FullStartUpAndProcessTest { private void injectSzrResponse() throws Exception { + setSzrResponseIdentityLink("/data/szr/szr_resp_valid_1.xml"); + when(szrMock, "getStammzahlEncrypted", any(), any()).thenReturn(vsz); val signContentResp = new SignContentResponseType(); final SignContentEntry signContentEntry = new SignContentEntry(); @@ -493,4 +501,17 @@ public class FullStartUpAndProcessTest { metadataProvider.addMetadataResolverIntoChain(fileSystemResolver); } + + private void setSzrResponseIdentityLink(String responseXmlPath) throws JAXBException, SZRException_Exception { + final JAXBContext jaxbContext = JAXBContext + .newInstance(szrservices.ObjectFactory.class, org.w3._2001._04.xmldsig_more.ObjectFactory.class, + org.w3._2000._09.xmldsig.ObjectFactory.class, + at.gv.e_government.reference.namespace.persondata._20020228.ObjectFactory.class); + final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + final GetIdentityLinkEidasResponse szrResponse = (GetIdentityLinkEidasResponse) jaxbUnmarshaller + .unmarshal(this.getClass().getResourceAsStream(responseXmlPath)); + org.mockito.Mockito.when(szrMock.getIdentityLinkEidas(any(PersonInfoType.class))).thenReturn(szrResponse.getGetIdentityLinkReturn()); + + } + } -- cgit v1.2.3 From 49a945fa17ee06f38ddada441df7a1f29c58e317 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 1 Apr 2022 21:47:48 +0200 Subject: feat(szr): add configuration property to activate/deactivate work-around for insertErnp in case of IDA mode --- .../src/main/resources/application.properties | 2 +- .../specific/modules/auth/eidas/v2/Constants.java | 4 + .../modules/auth/eidas/v2/szr/SzrClient.java | 25 ++++- .../eidas/v2/tasks/CreateIdentityLinkTask.java | 27 ++++-- .../tasks/CreateIdentityLinkTaskEidNewTest.java | 101 +++++++++++++++++++++ 5 files changed, 148 insertions(+), 11 deletions(-) (limited to 'connector/src') diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties index e7437840..73a258d7 100644 --- a/connector/src/main/resources/application.properties +++ b/connector/src/main/resources/application.properties @@ -100,7 +100,7 @@ eidas.ms.auth.eIDAS.szrclient.eidasbind.mds.inject=false #Raw eIDAS Id data storage eidas.ms.auth.eIDAS.szrclient.workarounds.eidmapping.revisionlog.active=true - +eidas.ms.auth.eIDAS.szrclient.workarounds.use.getidentitylink.for.ida=true eidas.ms.auth.eIDAS.szrclient.params.setPlaceOfBirthIfAvailable=true eidas.ms.auth.eIDAS.szrclient.params.setBirthNameIfAvailable=true diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java index 1732a61a..08b1b315 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java @@ -132,6 +132,10 @@ public class Constants { public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_SQLLITEDATASTORE_ACTIVE = CONIG_PROPS_EIDAS_SZRCLIENT + ".workarounds.datastore.sqlite.active"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_IDA_VSZ_IDL = + CONIG_PROPS_EIDAS_SZRCLIENT + ".workarounds.use.getidentitylink.for.ida"; + + // http endpoint descriptions public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post"; public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect"; diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java index 5558fdfd..e000a2e4 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java @@ -226,15 +226,15 @@ public class SzrClient { * Request a encryped baseId from SRZ. * * @param personInfo Minimum dataset of person + * @param insertErnp insertErnp flag on SZR request * @return encrypted baseId * @throws SzrCommunicationException In case of a SZR error */ - public String getEncryptedStammzahl(final PersonInfoType personInfo) - throws SzrCommunicationException { - + public String getEncryptedStammzahl(final PersonInfoType personInfo, boolean insertErnp) + throws SzrCommunicationException{ final String resp; try { - resp = this.szr.getStammzahlEncrypted(personInfo, false); + resp = this.szr.getStammzahlEncrypted(personInfo, insertErnp); } catch (SZRException_Exception e) { throw new SzrCommunicationException("ernb.02", new Object[]{e.getMessage()}, e); } @@ -244,6 +244,23 @@ public class SzrClient { } return resp; + + } + + + + + + /** + * Request a encrypted baseId from SRZ without insertErnp. + * + * @param personInfo Minimum dataset of person + * @return encrypted baseId + * @throws SzrCommunicationException In case of a SZR error + */ + public String getEncryptedStammzahl(final PersonInfoType personInfo) + throws SzrCommunicationException { + return getEncryptedStammzahl(personInfo, false); } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java index 4a501ed6..d08d8362 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java @@ -150,12 +150,9 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { if (pendingReq.getServiceProviderConfiguration() .isConfigurationValue(MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE, false)) { - // work-around, because getEncryptedStammzahl does not support insertERnP for eIDAS entities - SzrResultHolder idlResult = requestSzrForIdentityLink(personInfo); - - // get encrypted baseId - String vsz = szrClient.getEncryptedStammzahl(buildGetEncryptedBaseIdReq(idlResult.identityLink)); - + // get VSZ + String vsz = getVszForPerson(personInfo); + //write revision-Log entry and extended infos personal-identifier mapping revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.SZR_VSZ_RECEIVED); writeExtendedRevisionLogEntry(simpleAttrMap, eidData); @@ -224,6 +221,24 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { } } + private String getVszForPerson(PersonInfoType personInfo) throws SzrCommunicationException, EaafException { + if (basicConfig.getBasicConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_IDA_VSZ_IDL, true)) { + log.debug("IDA workaround is active. Requesting IDL to insert person into ERnP .... "); + + // work-around, because getEncryptedStammzahl does not support insertERnP for eIDAS entities + SzrResultHolder idlResult = requestSzrForIdentityLink(personInfo); + + // get encrypted baseId + return szrClient.getEncryptedStammzahl(buildGetEncryptedBaseIdReq(idlResult.identityLink)); + + + } else { + return szrClient.getEncryptedStammzahl(personInfo, true); + + } + } + private PersonInfoType buildGetEncryptedBaseIdReq(IIdentityLink identityLink) throws EaafBuilderException { log.debug("Generating getVsz request from identityLink information ... "); final PersonInfoType personInfo = new PersonInfoType(); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java index 720365fe..fbc070a9 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java @@ -141,6 +141,7 @@ public class CreateIdentityLinkTaskEidNewTest { RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); basicConfig.putConfigValue("eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution", "false"); + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.szrclient.workarounds.use.getidentitylink.for.ida", "true"); final Map spConfig = new HashMap<>(); spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp"); @@ -302,6 +303,106 @@ public class CreateIdentityLinkTaskEidNewTest { } + + + @Test + public void successfulProcessWithStandardInfosWithoutIdl() throws Exception { + //initialize test + basicConfig.putConfigValue("eidas.ms.auth.eIDAS.szrclient.workarounds.use.getidentitylink.for.ida", "false"); + + String vsz = RandomStringUtils.randomNumeric(10); + when(szrMock, "getStammzahlEncrypted", any(), any()).thenReturn(vsz); + val signContentResp = new SignContentResponseType(); + final SignContentEntry signContentEntry = new SignContentEntry(); + signContentEntry.setValue(RandomStringUtils.randomAlphanumeric(10)); + signContentResp.getOut().add(signContentEntry); + when(szrMock, "signContent", any(), any(), any()).thenReturn(signContentResp); + + String randomTestSp = RandomStringUtils.randomAlphabetic(10); + String bindingPubKey = RandomStringUtils.randomAlphabetic(10); + pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_REQUESTERID, randomTestSp); + pendingReq.setRawDataToTransaction(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, bindingPubKey); + + //perform test + task.execute(pendingReq, executionContext); + + //validate state + // check if pendingRequest was stored + IRequest storedPendingReq = requestStorage.getPendingRequest(pendingReq.getPendingRequestId()); + Assert.assertNotNull("pendingReq not stored", storedPendingReq); + + //check data in session + final AuthProcessDataWrapper authProcessData = storedPendingReq.getSessionData(AuthProcessDataWrapper.class); + Assert.assertNotNull("AuthProcessData", authProcessData); + Assert.assertNotNull("eidasBind", authProcessData.getGenericDataFromSession(Constants.EIDAS_BIND, String.class)); + + // check authblock signature + String authBlock = authProcessData.getGenericDataFromSession(Constants.SZR_AUTHBLOCK, String.class); + Assert.assertNotNull("AuthBlock", authBlock); + final AlgorithmConstraints constraints = new AlgorithmConstraints(ConstraintType.PERMIT, + BINDING_AUTH_ALGORITHM_WHITELIST_SIGNING.toArray(new String[BINDING_AUTH_ALGORITHM_WHITELIST_SIGNING.size()])); + Pair keyStore = getKeyStore(); + X509Certificate[] trustedCerts = EaafKeyStoreUtils + .getPrivateKeyAndCertificates(keyStore.getFirst(), ALIAS, PW.toCharArray(), true, "junit").getSecond(); + JwsResult result = JoseUtils.validateSignature(authBlock, Arrays.asList(trustedCerts), constraints); + Assert.assertTrue("AuthBlock not valid", result.isValid()); + JsonNode authBlockJson = mapper.readTree(result.getPayLoad()); + Assert.assertNotNull("deserialized AuthBlock", authBlockJson); + + Assert.assertNotNull("no piiTransactionId in pendingRequesdt", + storedPendingReq.getUniquePiiTransactionIdentifier()); + Assert.assertEquals("piiTransactionId", storedPendingReq.getUniquePiiTransactionIdentifier(), + authBlockJson.get("piiTransactionId").asText()); + Assert.assertEquals("appId", randomTestSp, authBlockJson.get("appId").asText()); + Assert.assertFalse("'challenge' is null", authBlockJson.get("challenge").asText().isEmpty()); + Assert.assertFalse("'timestamp' is null", authBlockJson.get("timestamp").asText().isEmpty()); + Assert.assertTrue("binding pubKey", authBlockJson.has("bindingPublicKey")); + Assert.assertEquals("binding PubKey", bindingPubKey, authBlockJson.get("bindingPublicKey").asText()); + + Assert.assertTrue("EID process", authProcessData.isEidProcess()); + Assert.assertTrue("foreigner process", authProcessData.isForeigner()); + Assert.assertEquals("EID-ISSUING_NATION", "LU", + authProcessData.getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class)); + Assert.assertNotNull("LoA is null", authProcessData.getQaaLevel()); + Assert.assertEquals("LoA", response.getLevelOfAssurance(), + authProcessData.getQaaLevel()); + + // check vsz request + ArgumentCaptor argument4 = ArgumentCaptor.forClass(PersonInfoType.class); + ArgumentCaptor argument5 = ArgumentCaptor.forClass(Boolean.class); + verify(szrMock, times(1)).getStammzahlEncrypted(argument4.capture(), argument5.capture()); + + Boolean param5 = argument5.getValue(); + Assert.assertTrue("insertERnP flag", param5); + PersonInfoType person = argument4.getValue(); + Assert.assertEquals("FamilyName", + response.getAttributes().getAttributeValuesByFriendlyName("FamilyName").getFirstValue( + response.getAttributes().getDefinitionsByFriendlyName("FamilyName").iterator().next()), + person.getPerson().getName().getFamilyName()); + Assert.assertEquals("GivenName", + response.getAttributes().getAttributeValuesByFriendlyName("FirstName").getFirstValue( + response.getAttributes().getDefinitionsByFriendlyName("FirstName").iterator().next()), + person.getPerson().getName().getGivenName()); + Assert.assertEquals("DateOfBirth", + response.getAttributes().getAttributeValuesByFriendlyName("DateOfBirth").getFirstValue( + response.getAttributes().getDefinitionsByFriendlyName("DateOfBirth").iterator().next()) + .toString().split("T")[0], + person.getPerson().getDateOfBirth()); + + Assert.assertNull("PlaceOfBirth", person.getPerson().getPlaceOfBirth()); + Assert.assertNull("BirthName", person.getPerson().getAlternativeName()); + + Assert.assertEquals("CitizenCountry", "LU", person.getTravelDocument().getIssuingCountry()); + Assert.assertEquals("DocumentType", "ELEKTR_DOKUMENT", person.getTravelDocument().getDocumentType()); + + Assert.assertEquals("Identifier", + response.getAttributes().getAttributeValuesByFriendlyName("PersonIdentifier").getFirstValue( + response.getAttributes().getDefinitionsByFriendlyName("PersonIdentifier").iterator().next()) + .toString().split("/")[2], + person.getTravelDocument().getDocumentNumber()); + + } + @Test public void successfulProcessWithStandardInfos() throws Exception { //initialize test -- cgit v1.2.3 From 791dc8acd7edbf22b98c2be111d420e61ebb39e6 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 5 Apr 2022 08:52:50 +0200 Subject: build(assembly): add histroy.txt into release package --- connector/src/assembly/assembly_dir.xml | 1 + connector/src/assembly/assembly_zip.xml | 1 + 2 files changed, 2 insertions(+) (limited to 'connector/src') diff --git a/connector/src/assembly/assembly_dir.xml b/connector/src/assembly/assembly_dir.xml index 59437be6..bc12a470 100644 --- a/connector/src/assembly/assembly_dir.xml +++ b/connector/src/assembly/assembly_dir.xml @@ -44,6 +44,7 @@ readme_${project.version}.txt readme_${project.version}.md + history.txt eIDAS_Ref_Impl/* handbook/* diff --git a/connector/src/assembly/assembly_zip.xml b/connector/src/assembly/assembly_zip.xml index 43877283..dcb7dab0 100644 --- a/connector/src/assembly/assembly_zip.xml +++ b/connector/src/assembly/assembly_zip.xml @@ -44,6 +44,7 @@ readme_${project.version}.txt readme_${project.version}.md + history.txt eIDAS_Ref_Impl/* handbook/* -- cgit v1.2.3