diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java index e4ae01066..fde453920 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java @@ -22,30 +22,52 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.verification; +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.DateTime; import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.EncryptedAssertion; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.encryption.Decrypter; +import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver; import org.opensaml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.security.MetadataCriteria; import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver; +import org.opensaml.xml.encryption.DecryptionException; +import org.opensaml.xml.encryption.InlineEncryptedKeyResolver; +import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver; import org.opensaml.xml.security.CriteriaSet; import org.opensaml.xml.security.credential.UsageType; import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.criteria.UsageCriteria; +import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver; +import org.opensaml.xml.security.x509.X509Credential; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.validation.ValidationException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; +import at.gv.egovernment.moa.logging.Logger; public class SAMLVerificationEngine { public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { - if (msg instanceof MOARequest) - verifyRequest(((MOARequest)msg).getSamlRequest(), sigTrustEngine); + if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof RequestAbstractType) + verifyRequest(((RequestAbstractType)((MOARequest)msg).getSamlRequest()), sigTrustEngine); else verifyResponse(((MOAResponse)msg).getResponse(), sigTrustEngine); @@ -102,4 +124,88 @@ public class SAMLVerificationEngine { } } + public static void validateAssertion(Response samlResp, boolean validateDestination) throws AssertionValidationExeption { + try { + if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); + + if (validateDestination && !samlResp.getDestination().startsWith( + PVPConfiguration.getInstance().getIDPPublicPath())) { + Logger.warn("PVP 2.1 assertion destination does not match to IDP URL"); + throw new AssertionValidationExeption("PVP 2.1 assertion destination does not match to IDP URL", null); + + } + + //check encrypted Assertion + List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions(); + if (encryAssertionList != null && encryAssertionList.size() > 0) { + //decrypt assertions + + Logger.debug("Found encryped assertion. Start decryption ..."); + + X509Credential authDecCredential = CredentialProvider.getIDPAssertionEncryptionCredential(); + + StaticKeyInfoCredentialResolver skicr = + new StaticKeyInfoCredentialResolver(authDecCredential); + + ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); + encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() ); + + Decrypter samlDecrypter = + new Decrypter(null, skicr, encryptedKeyResolver); + + for (EncryptedAssertion encAssertion : encryAssertionList) { + saml2assertions.add(samlDecrypter.decrypt(encAssertion)); + + } + + Logger.debug("Assertion decryption finished. "); + + } else { + saml2assertions.addAll(samlResp.getAssertions()); + + } + + for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { + + Conditions conditions = saml2assertion.getConditions(); + DateTime notbefore = conditions.getNotBefore(); + DateTime notafter = conditions.getNotOnOrAfter(); + if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) { + Logger.warn("PVP2 Assertion is out of Date"); + saml2assertions.remove(saml2assertion); + + } + } + + if (saml2assertions.isEmpty()) { + Logger.info("No valid PVP 2.1 assertion received."); + throw new AssertionValidationExeption("No valid PVP 2.1 assertion received.", null); + } + + samlResp.getAssertions().clear(); + samlResp.getEncryptedAssertions().clear(); + samlResp.getAssertions().addAll(saml2assertions); + + } else { + Logger.info("PVP 2.1 assertion includes an error. Receive errorcode " + + samlResp.getStatus().getStatusCode().getValue()); + throw new AssertionValidationExeption("PVP 2.1 assertion includes an error. Receive errorcode " + + samlResp.getStatus().getStatusCode().getValue(), null); + } + + } catch (CredentialsNotAvailableException e) { + Logger.warn("Assertion decrypt FAILED - No Credentials", e); + throw new AssertionValidationExeption("Assertion decrypt FAILED - No Credentials", null, e); + + } catch (DecryptionException e) { + Logger.warn("Assertion decrypt FAILED.", e); + throw new AssertionValidationExeption("Assertion decrypt FAILED.", null, e); + + } catch (ConfigurationException e) { + throw new AssertionValidationExeption("pvp.12", null, e); + } + } } |