diff options
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2')
4 files changed, 967 insertions, 1 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 1183bb49..b6171e97 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 @@ -26,7 +26,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @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/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/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); + + } + + +} |