diff options
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/test/java')
9 files changed, 1423 insertions, 88 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java index 3ba4629e..22ee389f 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java @@ -28,7 +28,7 @@ import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ - "/spring/test_eaaf_core_spring_config.beans.xml", + "/spring/test_eaaf_core_map_config.beans.xml", "/spring/SpringTest-context_lazy.xml" }) @TestPropertySource(locations = {"/config/config_1.props"}) diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java new file mode 100644 index 00000000..67c59dec --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java @@ -0,0 +1,56 @@ +package at.gv.egiz.eaaf.modules.pvp2.test; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.springframework.core.io.Resource; + +import at.gv.egiz.eaaf.core.test.TestConstants; +import at.gv.egiz.eaaf.modules.pvp2.Pvp2SProfileCoreSpringResourceProvider; + + + +@RunWith(BlockJUnit4ClassRunner.class) +public class Pvp2SProfileCoreSpringResourceProviderTest { + + @Test + public void testSpringConfig() { + final Pvp2SProfileCoreSpringResourceProvider test = + new Pvp2SProfileCoreSpringResourceProvider(); + for (final Resource el : test.getResourcesToLoad()) { + try { + IOUtils.toByteArray(el.getInputStream()); + + } catch (final IOException e) { + Assert.fail("Ressouce: " + el.getFilename() + " not found"); + } + + } + + Assert.assertNotNull("no Name", test.getName()); + Assert.assertNull("Find package definitions", test.getPackagesToScan()); + + } + + @Test + public void testSpILoaderConfig() { + final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH); + try { + final String spiFile = IOUtils.toString(el, "UTF-8"); + + Assert.assertEquals("Wrong classpath in SPI file", + Pvp2SProfileCoreSpringResourceProvider.class.getName(), spiFile); + + + } catch (final IOException e) { + Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found"); + + } + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java new file mode 100644 index 00000000..44cdf111 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java @@ -0,0 +1,147 @@ +package at.gv.egiz.eaaf.modules.pvp2.test; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; + +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotAllowedException; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QaaLevelVerifier; + +@RunWith(BlockJUnit4ClassRunner.class) +public class QaaLevelVerifierTest { + + QaaLevelVerifier verifyer = new QaaLevelVerifier(); + + @Test + public void matchingModeUnknown() { + String matchingMode = "notExist"; + List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL); + + try { + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + try { + QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + } + + @Test + public void matchingMinimumRequiredLow() throws QaaNotAllowedException { + String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM; + List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_LOW); + + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode); + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode); + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode); + + try { + QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + } + + @Test + public void matchingMinimumRequiredSubstantial() throws QaaNotAllowedException { + String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM; + List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL); + + try { + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode); + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode); + + try { + QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + } + + @Test + public void matchingMinimumRequiredHigh() throws QaaNotAllowedException { + String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM; + List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_HIGH); + + try { + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + try { + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode); + + try { + QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + } + + @Test + public void matchingExact1() throws QaaNotAllowedException { + String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_EXACT; + List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL, EaafConstants.EIDAS_LOA_LOW); + + try { + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode); + QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode); + + try { + QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode); + Assert.fail("LoA should not be allowed"); + + } catch (QaaNotAllowedException e) { + + } + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java new file mode 100644 index 00000000..66e87537 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java @@ -0,0 +1,720 @@ +package at.gv.egiz.eaaf.modules.pvp2.test; + +import java.util.ArrayList; +import java.util.List; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafProtocolException; +import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider; + +import org.joda.time.DateTime; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.core.xml.io.UnmarshallingException; +import org.opensaml.core.xml.util.XMLObjectSupport; +import org.opensaml.saml.common.xml.SAMLConstants; +import org.opensaml.saml.saml2.core.Assertion; +import org.opensaml.saml.saml2.core.AuthnRequest; +import org.opensaml.saml.saml2.core.EncryptedAssertion; +import org.opensaml.saml.saml2.core.Issuer; +import org.opensaml.saml.saml2.core.Response; +import org.opensaml.saml.saml2.core.StatusCode; +import org.opensaml.saml.saml2.encryption.Encrypter; +import org.opensaml.saml.saml2.encryption.Encrypter.KeyPlacement; +import org.opensaml.security.x509.X509Credential; +import org.opensaml.xmlsec.SecurityConfigurationSupport; +import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters; +import org.opensaml.xmlsec.encryption.support.EncryptionException; +import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters; +import org.opensaml.xmlsec.keyinfo.KeyInfoGeneratorFactory; +import org.opensaml.xmlsec.signature.support.SignatureConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.Assert; +import org.w3c.dom.Element; + +import net.shibboleth.utilities.java.support.xml.XMLParserException; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml", + "/spring/test_eaaf_core_spring_config.beans.xml" }) +@TestPropertySource(locations = { "/config/config_1.props" }) +public class SamlVerificationEngineTest { + + @Autowired + private PvpMetadataResolverFactory metadataResolverFactory; + @Autowired + private SamlVerificationEngine verifyEngine; + @Autowired + private DummyCredentialProvider credentialProvider; + + @Autowired DummyMetadataProvider metadataProvider; + @Autowired IConfiguration authConfig; + + /** + * JUnit class initializer. + * + * @throws Exception In case of an OpenSAML3 initialization error + */ + @BeforeClass + public static void classInitializer() throws Exception { + EaafOpenSaml3xInitializer.eaafInitialize(); + + } + + @Test + public void validateSamlRequestSuccess() throws SecurityException, Exception { + + final String authnReqPath = "/data/AuthRequest_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"; + final String spEntityId = metadataPath; + + final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg = + initializeAuthnRequest(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final PvpSProfileRequest msg = new PvpSProfileRequest( + inputMsg.getFirst(), + SAMLConstants.SAML2_POST_BINDING_URI); + msg.setEntityID(spEntityId); + + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + + } + + @Test + public void validateSamlRequestWrongSignature() throws SecurityException, Exception { + + final String authnReqPath = "/data/AuthRequest_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = metadataPath; + + final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg = + initializeAuthnRequest(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + metadataProvider.addMetadataResolverIntoChain(inputMsg.getSecond()); + + final PvpSProfileRequest msg = new PvpSProfileRequest( + inputMsg.getFirst(), + SAMLConstants.SAML2_POST_BINDING_URI); + msg.setEntityID(spEntityId); + + try { + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + org.junit.Assert.fail("Wrong signature not detected"); + + } catch (final Exception e) { + Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType"); + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.10", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void validateSamlInvalidRequest() throws SecurityException, Exception { + + final String authnReqPath = "/data/AuthRequest_without_sig_missing_id.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = metadataPath; + + final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg = + initializeAuthnRequest(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + metadataProvider.addMetadataResolverIntoChain(inputMsg.getSecond()); + + final PvpSProfileRequest msg = new PvpSProfileRequest( + inputMsg.getFirst(), + SAMLConstants.SAML2_POST_BINDING_URI); + msg.setEntityID(spEntityId); + + try { + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + org.junit.Assert.fail("invalid request not detected"); + + } catch (final Exception e) { + Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType"); + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.03", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void validateSamlRequestWrongSignatureAlg() throws SecurityException, Exception { + + final String authnReqPath = "/data/AuthRequest_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = metadataPath; + + metadataProvider.runGarbageCollector(); + + final EaafX509Credential cred = credentialProvider.getMetaDataSigningCredential(); + cred.setSignatureAlgorithmForSigning(SignatureConstants.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5); + final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg = + initializeAuthnRequest(spEntityId, metadataPath, authnReqPath, + cred); + + final PvpSProfileRequest msg = new PvpSProfileRequest( + inputMsg.getFirst(), + SAMLConstants.SAML2_POST_BINDING_URI); + msg.setEntityID(spEntityId); + + try { + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + org.junit.Assert.fail("Wrong SigAlg not detected"); + + } catch (final Exception e) { + Assert.isInstanceOf(EaafProtocolException.class, e, "Wrong exceptionType"); + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.99", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyResponseSuccessTest() throws Pvp2InternalErrorException, SecurityException, Exception { + metadataProvider.runGarbageCollector(); + + final String authnReqPath = "/data/Response_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"; + final String spEntityId = metadataPath; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final PvpSProfileResponse msg = new PvpSProfileResponse( + inputMsg.getFirst()); + msg.setEntityID(spEntityId); + + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + + } + + @Test + public void verifyResponseSuccessSecondTest() + throws Pvp2InternalErrorException, SecurityException, Exception { + + final String authnReqPath = "/data/Response_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"; + final String spEntityId = metadataPath; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + verifyEngine.verifyIdpResponse(inputMsg.getFirst(), + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + + } + + @Test + public void verifySpResponse() + throws Pvp2InternalErrorException, SecurityException, Exception { + + final String authnReqPath = "/data/Response_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"; + final String spEntityId = metadataPath; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + verifyEngine.verifySloResponse(inputMsg.getFirst(), + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + + } + + @Test + public void verifyResponseWithoutId() throws Pvp2InternalErrorException, SecurityException, Exception { + + final String authnReqPath = "/data/Response_with_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"; + final String spEntityId = metadataPath; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final PvpSProfileResponse msg = new PvpSProfileResponse( + inputMsg.getFirst()); + msg.setEntityID(spEntityId); + + try { + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + org.junit.Assert.fail("Wrong XML schema not detected"); + + } catch (final Exception e) { + Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType"); + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.03", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyResponseWrongTrust() throws Pvp2InternalErrorException, SecurityException, Exception { + + final String authnReqPath = "/data/Response_without_sig_1.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = metadataPath; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final PvpSProfileResponse msg = new PvpSProfileResponse( + inputMsg.getFirst()); + msg.setEntityID(spEntityId); + + try { + verifyEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); + org.junit.Assert.fail("No TrustedCert not detected"); + + } catch (final Exception e) { + Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType"); + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.10", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionSucessNotEncrypted() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + + + } + + @Test + public void verifyAssertionWrongAudiency() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + try { + verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + org.junit.Assert.fail("Wrong Audiency not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongStatusCode() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getStatus().getStatusCode().setValue(StatusCode.RESPONDER); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + org.junit.Assert.fail("Wrong StatusCode not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.17", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongIssueInstant() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.setIssueInstant(DateTime.now().plusMinutes(10)); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.14", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionNoContitions() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).setConditions(null); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongContitions() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongContitionsAudienceRestrictions() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now()); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(15)); + response.getAssertions().get(0).getConditions().getAudienceRestrictions().clear(); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongContitionsNotBefore() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now().plusMinutes(10)); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(15)); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionWrongContitionsNotOnOrAfter() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now()); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().minusMinutes(5)); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyAssertionValidContitions() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now()); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5)); + + + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", true); + + } + + @Test + public void verifyEncAssertionWrongKey() throws SamlSigningException, Pvp2MetadataException, + CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption { + final String authnReqPath = "/data/Asserion_enc_no_key.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://eid.a-sit.at/Shibboleth.sso/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + try { + verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + org.junit.Assert.fail("Wrong date not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.16", ((EaafException) e).getErrorId()); + + } + } + + @Test + public void verifyEncAssertion() throws Exception { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now()); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5)); + + final Element secAssertionElement = XMLObjectSupport.marshall(response.getAssertions().get(0)); + + secAssertionElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xs", "http://www.w3.org/2001/XMLSchema"); + final Assertion secAssertion = (Assertion) XMLObjectSupport.getUnmarshaller(secAssertionElement) + .unmarshall(secAssertionElement); + + final EncryptedAssertion encAsserton = doEncryption(secAssertion, + credentialProvider.getMetaDataSigningCredential(), + authConfig); + response.getEncryptedAssertions().add(encAsserton); + + + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + + org.junit.Assert.assertEquals("Assertions not match", 2, response.getAssertions().size()); + + } + + @Test + public void verifyEncAssertionWrongSchema() throws Exception { + final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml"; + final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml"; + final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/"; + + final Pair<Response, IPvp2MetadataProvider> inputMsg = + initializeResponse(spEntityId, metadataPath, authnReqPath, + credentialProvider.getMetaDataSigningCredential()); + + final Response response = inputMsg.getFirst(); + response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now()); + response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5)); + + final Element secAssertionElement = XMLObjectSupport.marshall(response.getAssertions().get(0)); + + final Assertion secAssertion = (Assertion) XMLObjectSupport.getUnmarshaller(secAssertionElement) + .unmarshall(secAssertionElement); + + final EncryptedAssertion encAsserton = doEncryption(secAssertion, + credentialProvider.getMetaDataSigningCredential(), + authConfig); + response.getEncryptedAssertions().add(encAsserton); + + try { + verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(), + spEntityId, "jUnit Test", false); + + org.junit.Assert.fail("Wrong XML Schema not detected"); + + } catch (final SamlAssertionValidationExeption e) { + org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId()); + + } + + } + + private Pair<Response, IPvp2MetadataProvider> initializeResponse(String spEntityId, String metadataPath, + String authnReqPath, EaafX509Credential credential) + throws SamlSigningException, XMLParserException, UnmarshallingException, Pvp2MetadataException { + final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider( + metadataPath, null, "jUnit metadata resolver", null); + + final Response authnReq = (Response) XMLObjectSupport.unmarshallFromInputStream( + XMLObjectProviderRegistrySupport.getParserPool(), + SamlVerificationEngineTest.class.getResourceAsStream(authnReqPath)); + authnReq.setIssueInstant(DateTime.now()); + final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); + issuer.setValue(spEntityId); + authnReq.setIssuer(issuer); + + return Pair.newInstance( + Saml2Utils.signSamlObject(authnReq, credential, true), + mdResolver); + } + + private Pair<AuthnRequest, IPvp2MetadataProvider> initializeAuthnRequest(String spEntityId, + String metadataPath, String authnReqPath, EaafX509Credential credential) + throws SamlSigningException, CredentialsNotAvailableException, + XMLParserException, UnmarshallingException, Pvp2InternalErrorException, Pvp2MetadataException { + + final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider( + metadataPath, null, "jUnit metadata resolver", null); + + final AuthnRequest authnReq = (AuthnRequest) XMLObjectSupport.unmarshallFromInputStream( + XMLObjectProviderRegistrySupport.getParserPool(), + SamlVerificationEngineTest.class.getResourceAsStream(authnReqPath)); + authnReq.setIssueInstant(DateTime.now()); + final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); + issuer.setValue(spEntityId); + authnReq.setIssuer(issuer); + + return Pair.newInstance( + Saml2Utils.signSamlObject(authnReq, credential, true), + mdResolver); + + } + + private static EncryptedAssertion doEncryption(Assertion assertion, + X509Credential encryptionCredentials, IConfiguration authConfig) + throws Exception { + try { + final String keyEncAlg = Saml2Utils.getKeyOperationAlgorithmFromCredential( + encryptionCredentials, + authConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_RSA_ALG, + PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_RSA), + authConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_EC_ALG, + PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_EC)); + + final DataEncryptionParameters dataEncParams = new DataEncryptionParameters(); + dataEncParams.setAlgorithm(authConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_DATA, PvpConstants.DEFAULT_SYM_ENCRYPTION_METHODE)); + + final List<KeyEncryptionParameters> keyEncParamList = new ArrayList<>(); + final KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); + keyEncParam.setEncryptionCredential(encryptionCredentials); + keyEncParam.setAlgorithm(keyEncAlg); + + final KeyInfoGeneratorFactory kigf = + SecurityConfigurationSupport.getGlobalEncryptionConfiguration() + .getKeyTransportKeyInfoGeneratorManager().getDefaultManager().getFactory(encryptionCredentials); + keyEncParam.setKeyInfoGenerator(kigf.newInstance()); + keyEncParamList.add(keyEncParam); + + final Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); + samlEncrypter.setKeyPlacement(KeyPlacement.PEER); + + return samlEncrypter.encrypt(assertion); + + } catch (final EncryptionException | SamlSigningException e1) { + throw new Exception(e1); + + } + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java index 76dba510..8833202a 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java @@ -9,27 +9,6 @@ import java.util.Map; import javax.xml.parsers.ParserConfigurationException; -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration; -import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory; -import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; -import at.gv.egiz.eaaf.core.impl.utils.DomUtils; -import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; -import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; -import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare; -import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; -import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.joda.time.DateTime; @@ -38,14 +17,19 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.opensaml.core.xml.XMLObject; import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.core.xml.io.MarshallingException; import org.opensaml.core.xml.io.Unmarshaller; import org.opensaml.core.xml.io.UnmarshallerFactory; import org.opensaml.core.xml.io.UnmarshallingException; +import org.opensaml.core.xml.schema.XSString; import org.opensaml.core.xml.util.XMLObjectSupport; import org.opensaml.messaging.decoder.MessageDecodingException; import org.opensaml.messaging.encoder.MessageEncodingException; import org.opensaml.saml.common.SignableSAMLObject; +import org.opensaml.saml.saml2.core.AuthnRequest; +import org.opensaml.saml.saml2.core.Issuer; import org.opensaml.saml.saml2.core.RequestAbstractType; import org.opensaml.saml.saml2.core.StatusResponseType; import org.opensaml.saml.saml2.metadata.SPSSODescriptor; @@ -58,7 +42,34 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.w3c.dom.Element; import org.xml.sax.SAXException; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration; +import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory; +import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; +import at.gv.egiz.eaaf.core.impl.utils.DomUtils; +import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest; import net.shibboleth.utilities.java.support.net.URIComparator; +import net.shibboleth.utilities.java.support.xml.SerializeSupport; import net.shibboleth.utilities.java.support.xml.XMLParserException; import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; @@ -125,6 +136,34 @@ public class PostBindingTest { } @Test + public void wrongPostBindingEncoding() throws MessageDecodingException, SecurityException, + IOException, Pvp2MetadataException { + final String serviceUrl = "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post"; + + final IPvp2MetadataProvider metadataProvider = + metadataResolverFactory.createMetadataProvider( + "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null); + + final URIComparator comparator = new EaafUriCompare(serviceUrl); + + final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray( + PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"))); + httpReq.setMethod("POST"); + httpReq.addParameter("SAMLRequest", b64AuthnReq); + httpReq.setParameter("SAMLEncoding", RandomStringUtils.randomAlphabetic(5)); + + try { + bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator); + Assert.fail("Missing signature not detected"); + + } catch (final Pvp2Exception e) { + Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId()); + + } + + } + + @Test public void decodeRequestWrongEndpoint() throws MessageDecodingException, SecurityException, IOException, Pvp2MetadataException { final String serviceUrl = "https://wrongEndpoint/pvp2/post"; @@ -315,6 +354,73 @@ public class PostBindingTest { } @Test + public void decodeRequestSuccessWithRequestAttributes() throws MessageDecodingException, SecurityException, + IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, MarshallingException { + final String serviceUrl = "https://eidas-test.bmi.gv.at/ms_connector/pvp/post"; + final String relayState = RandomStringUtils.randomAlphanumeric(10); + + final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream( + XMLObjectProviderRegistrySupport.getParserPool(), + PostBindingTest.class.getResourceAsStream("/data/eIDAS_connector_authn.xml")); + authnReq.setIssueInstant(DateTime.now()); + Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); + issuer.setValue("https://demo.egiz.gv.at/demoportal_demologin/"); + authnReq.setIssuer(issuer); + + RequestAbstractType signedAuthn = Saml2Utils.signSamlObject(authnReq, credentialProvider.getMessageSigningCredential(), true); + Element signedElement = XMLObjectSupport.getMarshaller(signedAuthn).marshall(signedAuthn); + final String b64AuthnReq = + Base64.getEncoder().encodeToString(SerializeSupport.nodeToString(signedElement).getBytes("UTF-8")); + httpReq.setMethod("POST"); + httpReq.addParameter("SAMLRequest", b64AuthnReq); + httpReq.addParameter("RelayState", relayState); + + final IPvp2MetadataProvider metadataProvider = + metadataResolverFactory.createMetadataProvider( + "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null); + + final URIComparator comparator = new EaafUriCompare(serviceUrl); + + final InboundMessageInterface msg = + bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator); + + Assert.assertNotNull("PVP msg is null", msg); + Assert.assertNotNull("RelayState is not null", msg.getRelayState()); + Assert.assertEquals("RelayState not match", relayState, msg.getRelayState()); + Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage()); + Assert.assertNotNull("EntityId is null", msg.getEntityID()); + Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID()); + Assert.assertTrue("Wrong isVerified flag", msg.isVerified()); + + org.springframework.util.Assert.isInstanceOf(PvpSProfileRequest.class, msg, "Inbound message is of wrong type"); + org.springframework.util.Assert.isInstanceOf(AuthnRequest.class, ((PvpSProfileRequest)msg).getSamlRequest(), + "Inbound message is of wrong type"); + + AuthnRequest parsedAuthnReq = (AuthnRequest)((PvpSProfileRequest)msg).getSamlRequest(); + Assert.assertNotNull("No extension", parsedAuthnReq.getExtensions()); + Assert.assertNotNull("No extension child", parsedAuthnReq.getExtensions().getUnknownXMLObjects()); + Assert.assertEquals("extension child size", 1, parsedAuthnReq.getExtensions().getUnknownXMLObjects().size()); + + XMLObject reqAttrs = parsedAuthnReq.getExtensions().getUnknownXMLObjects().get(0); + org.springframework.util.Assert.isInstanceOf(EaafRequestedAttributes.class, reqAttrs, "Wrong requested Attributes type"); + EaafRequestedAttributes eaafReqAttrs = (EaafRequestedAttributes) reqAttrs; + Assert.assertNotNull("Req attr is null", eaafReqAttrs.getAttributes()); + Assert.assertFalse("Req attr is empty", eaafReqAttrs.getAttributes().isEmpty()); + Assert.assertEquals("Req attr size", 1, eaafReqAttrs.getAttributes().size()); + + EaafRequestedAttribute eaafReqAttr = eaafReqAttrs.getAttributes().get(0); + Assert.assertNotNull("Req Attibute is null", eaafReqAttr); + Assert.assertEquals("Req. Attr. Friendlyname", "EID-SECTOR-FOR-IDENTIFIER", eaafReqAttr.getFriendlyName()); + Assert.assertEquals("Req. Attr. Name", "urn:oid:1.2.40.0.10.2.1.1.261.34", eaafReqAttr.getName()); + + Assert.assertEquals("Req. Attr. Value size", 1, eaafReqAttr.getAttributeValues().size()); + org.springframework.util.Assert.isInstanceOf(XSString.class, eaafReqAttr.getAttributeValues().get(0), + "Wrong requested Attributes Value type"); + Assert.assertEquals("Req. Attr. Value", "urn:publicid:gv.at:cdid+BF", ((XSString)eaafReqAttr.getAttributeValues().get(0)).getValue()); + + } + + @Test public void decodeRequestSuccessWithoutRelayStateEcdsaSig() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException { final String serviceUrl = "http://testservice.org"; @@ -340,6 +446,13 @@ public class PostBindingTest { Assert.assertNotNull("EntityId is null", msg.getEntityID()); Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID()); Assert.assertTrue("Wrong isVerified flag", msg.isVerified()); + + //check if reconstraction from serialized form work well + ((InboundMessage)msg).setSamlMessage(null); + try { + Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage()); + + } catch (RuntimeException e) { } } @@ -367,6 +480,8 @@ public class PostBindingTest { Assert.assertNotNull("EntityId is null", msg.getEntityID()); Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID()); Assert.assertTrue("Wrong isVerified flag", msg.isVerified()); + + org.springframework.util.Assert.isInstanceOf(PvpSProfileResponse.class, msg, "Inbound message is of wrong type"); } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java index f85e5c2a..408729e3 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java @@ -2,36 +2,15 @@ package at.gv.egiz.eaaf.modules.pvp2.test.binding; import java.io.IOException; import java.net.URLDecoder; -import java.util.Base64; import javax.xml.parsers.ParserConfigurationException; -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; -import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; -import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; -import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; -import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException; -import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; -import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; -import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare; -import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; -import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.joda.time.DateTime; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; @@ -50,6 +29,24 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.xml.sax.SAXException; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; +import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; +import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest; import net.shibboleth.utilities.java.support.net.URIComparator; import net.shibboleth.utilities.java.support.net.URISupport; import net.shibboleth.utilities.java.support.xml.XMLParserException; @@ -129,6 +126,93 @@ public class RedirectBindingTest { } @Test + public void wrongHttpRequestMethod() throws MessageDecodingException, + SecurityException, IOException, Pvp2MetadataException { + final String serviceUrl = "http://testservice.org"; + + final IPvp2MetadataProvider metadataProvider = + metadataResolverFactory.createMetadataProvider( + "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null); + + final URIComparator comparator = new EaafUriCompare(serviceUrl); + + httpReq.setMethod("POST"); + httpReq.setRequestURI("http://testservice.org"); + httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%" + + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli" + + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps" + + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv" + + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402" + + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI" + + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2" + + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2" + + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86" + + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg" + + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc" + + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D"); + + httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter( + httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8")); + httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter( + httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()), + "UTF-8")); + + try { + bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, + comparator); + Assert.fail("Missing signature not detected"); + + } catch (final Pvp2Exception e) { + Assert.assertEquals("Wrong errorCode", "internal.pvp.95", e.getErrorId()); + + } + } + + @Test + public void wrongRedirectBindingType() throws MessageDecodingException, + SecurityException, IOException, Pvp2MetadataException { + final String serviceUrl = "http://testservice.org"; + + final IPvp2MetadataProvider metadataProvider = + metadataResolverFactory.createMetadataProvider( + "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null); + + final URIComparator comparator = new EaafUriCompare(serviceUrl); + + httpReq.setMethod("POST"); + httpReq.setRequestURI("http://testservice.org"); + httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%" + + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli" + + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps" + + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv" + + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402" + + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI" + + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2" + + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2" + + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86" + + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg" + + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc" + + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D"); + + httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter( + httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8")); + httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter( + httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()), + "UTF-8")); + httpReq.setParameter("SAMLEncoding", RandomStringUtils.randomAlphabetic(5)); + + try { + bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, + comparator); + Assert.fail("Missing signature not detected"); + + } catch (final Pvp2Exception e) { + Assert.assertEquals("Wrong errorCode", "internal.pvp.95", e.getErrorId()); + + } + } + + @Test public void decodeRequestNoSignature() throws MessageDecodingException, SecurityException, IOException, Pvp2MetadataException { final String serviceUrl = "http://testservice.org"; @@ -169,7 +253,6 @@ public class RedirectBindingTest { Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId()); } - } @Test @@ -362,38 +445,6 @@ public class RedirectBindingTest { } - @Ignore - @Test - public void decodeRequestSuccessWithRelayState() throws MessageDecodingException, - SecurityException, IOException, Pvp2Exception { - final String serviceUrl = "http://testservice.org"; - final String relayState = RandomStringUtils.randomAlphanumeric(10); - - final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray( - RedirectBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml"))); - httpReq.setMethod("POST"); - httpReq.addParameter("SAMLRequest", b64AuthnReq); - httpReq.addParameter("RelayState", relayState); - - final IPvp2MetadataProvider metadataProvider = null; - - final URIComparator comparator = new EaafUriCompare(serviceUrl); - - final InboundMessageInterface msg = - bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, - comparator); - - Assert.assertNotNull("PVP msg is null", msg); - Assert.assertNotNull("RelayState is not null", msg.getRelayState()); - Assert.assertEquals("RelayState not match", relayState, msg.getRelayState()); - Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage()); - Assert.assertNotNull("EntityId is null", msg.getEntityID()); - Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg - .getEntityID()); - Assert.assertFalse("Wrong isVerified flag", msg.isVerified()); - - } - @Test public void decodeResponseSuccess() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException { diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java new file mode 100644 index 00000000..64ebe00c --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java @@ -0,0 +1,80 @@ +package at.gv.egiz.eaaf.modules.pvp2.test.dummy; + +import java.io.IOException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; + +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; + +import org.opensaml.saml.metadata.resolver.MetadataResolver; +import org.opensaml.saml.metadata.resolver.filter.MetadataFilter; +import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain; +import org.springframework.beans.factory.annotation.Autowired; + +public class DummyMetadataProvider extends AbstractChainingMetadataProvider { + + private final List<String> configuredMetadataUrls = new ArrayList<>(); + private String metadataProviderName; + + @Autowired PvpMetadataResolverFactory resolverFactory; + @Autowired IHttpClientFactory httpClientFactory; + private final MetadataFilterChain metadataFilters = new MetadataFilterChain(); + + @Override + protected String getMetadataUrl(String entityId) throws EaafConfigurationException { + return entityId; + + } + + @Override + protected MetadataResolver createNewMetadataProvider(String entityId) throws EaafConfigurationException, + IOException, CertificateException { + try { + return resolverFactory.createMetadataProvider(entityId, metadataFilters, entityId, null, + httpClientFactory.getHttpClient()); + + } catch (final Pvp2MetadataException e) { + throw new EaafConfigurationException("internal.pvp.04", new Object[] {entityId}, e); + + } + + } + + @Override + protected List<String> getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException { + return configuredMetadataUrls; + + } + + @Override + protected String getMetadataProviderId() { + return metadataProviderName; + + } + + public void addMetadataUrls(List<String> metadataUrls) { + configuredMetadataUrls.addAll(metadataUrls); + + } + + public void clearMetadataUrls() { + configuredMetadataUrls.clear(); + + } + + public void setMetadataProviderName(String name) { + metadataProviderName = name; + + } + + public void setMetadataFilters(List<MetadataFilter> filtersToUse) { + metadataFilters.setFilters(filtersToUse); + + } + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java new file mode 100644 index 00000000..8e00068f --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java @@ -0,0 +1,166 @@ +package at.gv.egiz.eaaf.modules.pvp2.test.metadata; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.core.criterion.EntityIdCriterion; +import org.opensaml.saml.criterion.EntityRoleCriterion; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml.saml2.metadata.SPSSODescriptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import net.shibboleth.utilities.java.support.resolver.CriteriaSet; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import okhttp3.HttpUrl; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml", + "/spring/test_eaaf_core_spring_config.beans.xml" }) +@TestPropertySource(locations = { "/config/config_1.props" }) +public class ChainingMetadataTest { + + private static MockWebServer mockWebServer; + private static HttpUrl mockServerUrl; + + @Autowired DummyMetadataProvider metadataProvider; + @Autowired PvpMetadataResolverFactory factory; + @Autowired IConfiguration authConfig; + @Autowired IHttpClientFactory httpFactory; + + + /** + * JUnit class initializer. + * + * @throws Exception In case of an OpenSAML3 initialization error + */ + @BeforeClass + public static void classInitializer() throws Exception { + EaafOpenSaml3xInitializer.eaafInitialize(); + + mockWebServer = new MockWebServer(); + mockServerUrl = mockWebServer.url("/sp/metadata"); + } + + @Test + public void runGarbageCollector() throws ResolverException, Pvp2MetadataException, + UnsupportedEncodingException, IOException { + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(new String(IOUtils.toByteArray( + MetadataResolverTest.class.getResourceAsStream( + "/data/pvp_metadata_moaid_test.xml")), "UTF-8")) + .setHeader("Content-Type", "text/xml")); + + final EntityDescriptor entityDesc = + metadataProvider.getEntityDescriptor("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + Assert.assertNotNull("EntityDesc is null", entityDesc); + + final IPvp2MetadataProvider provider2 = factory.createMetadataProvider( + "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit", null); + metadataProvider.addMetadataResolverIntoChain(provider2); + + final IPvp2MetadataProvider provider3 = factory.createMetadataProvider( + "classpath:/data/pvp_metadata_valid_with_entityCategory_egov.xml", null, "jUnit", null); + metadataProvider.addMetadataResolverIntoChain(provider3); + + final IPvp2MetadataProvider provider4 = factory.createMetadataProvider( + mockServerUrl.url().toString(), null, "jUnit", httpFactory.getHttpClient()); + metadataProvider.addMetadataResolverIntoChain(provider4); + + + + + metadataProvider.addMetadataUrls(Arrays.asList( + FileUtils.makeAbsoluteUrl("classpath:/data/pvp_metadata_junit_keystore.xml", + authConfig.getConfigurationRootDirectory()), mockServerUrl.url().toString())); + + metadataProvider.runGarbageCollector(); + + final EntityDescriptor entityDesc4 = + metadataProvider.getEntityDescriptor("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + Assert.assertNotNull("EntityDesc is null", entityDesc4); + + + metadataProvider.clearMetadataUrls(); + metadataProvider.runGarbageCollector(); + + final CriteriaSet criteria = new CriteriaSet(); + criteria.add(new EntityIdCriterion("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml")); + final EntityDescriptor entityDesc5 = metadataProvider.resolveSingle(criteria); + Assert.assertNotNull("EntityDesc is null", entityDesc5); + + + final CriteriaSet criteria6 = new CriteriaSet(); + criteria6.add(new EntityIdCriterion("classpath:/data/classpath:/data/pvp_metadata_junit_keystore.xml")); + final EntityDescriptor entityDesc6 = metadataProvider.resolveSingle(criteria6); + Assert.assertNull("EntityDesc not null", entityDesc6); + + metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + + metadataProvider.clear(); + + metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + + metadataProvider.clear("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + + Assert.assertFalse("Wrong refresh flag", metadataProvider.wasLastRefreshSuccess()); + + metadataProvider.getMetadataFilter(); + + metadataProvider.fullyDestroy(); + + metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + + final CriteriaSet criteria7 = new CriteriaSet(); + criteria7.add(new EntityIdCriterion("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml")); + final Iterable<EntityDescriptor> entityDesc7 = metadataProvider.resolve(criteria7); + Assert.assertNotNull("EntityDesc is null", entityDesc7); + Assert.assertTrue("is Empty", entityDesc7.iterator().hasNext()); + + final CriteriaSet criteria8 = new CriteriaSet(); + criteria8.add(new EntityIdCriterion("classpath:/data/classpath:/data/pvp_metadata_junit_keystore.xml")); + final Iterable<EntityDescriptor> entityDesc8 = metadataProvider.resolve(criteria8); + Assert.assertNotNull("EntityDesc not null", entityDesc8); + Assert.assertFalse("is not Empty", entityDesc8.iterator().hasNext()); + + metadataProvider.refresh(); + + metadataProvider.getLastRefresh(); + + metadataProvider.getLastSuccessfulRefresh(); + + metadataProvider.getLastUpdate(); + + metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"); + + + final CriteriaSet criteria9 = new CriteriaSet(); + criteria9.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME)); + final Iterable<EntityDescriptor> entityDesc9 = metadataProvider.resolve(criteria9); + Assert.assertNotNull("EntityDesc not null", entityDesc9); + + } + + +} diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java index f8402510..6cf81d2b 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java @@ -14,14 +14,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; -import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; - import org.apache.commons.lang3.RandomStringUtils; import org.junit.Assert; import org.junit.BeforeClass; @@ -49,6 +41,14 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider; import net.shibboleth.utilities.java.support.xml.XMLParserException; @@ -84,7 +84,7 @@ public class MetadataBuilderTest { TransformerException, ParserConfigurationException, IOException, SignatureException, XMLParserException, UnmarshallingException, CertificateException { - final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(false, true); + final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, false, true); //generate metadata final String metadata = metadataBuilder.buildPvpMetadata(config); @@ -102,7 +102,7 @@ public class MetadataBuilderTest { TransformerException, ParserConfigurationException, IOException, SignatureException, XMLParserException, UnmarshallingException, CertificateException { - final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, false); + final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, true, false); //generate metadata final String metadata = metadataBuilder.buildPvpMetadata(config); @@ -120,7 +120,7 @@ public class MetadataBuilderTest { TransformerException, ParserConfigurationException, IOException, SignatureException, XMLParserException, UnmarshallingException, CertificateException { - final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, true); + final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, true, true); //generate metadata final String metadata = metadataBuilder.buildPvpMetadata(config); @@ -155,7 +155,7 @@ public class MetadataBuilderTest { return entity; } - private IPvpMetadataBuilderConfiguration idpMetadataConfig(boolean buildSpInfos, boolean buildIdpInfos) { + public static IPvpMetadataBuilderConfiguration idpMetadataConfig(IPvp2CredentialProvider credentialProvider, boolean buildSpInfos, boolean buildIdpInfos) { return new IPvpMetadataBuilderConfiguration() { @Override |