- try {
- auto_ptr<ArtifactResponse> response(
- m_artifactResolver->resolve(
- securityMech,
- *(artifact2.get()),
- dynamic_cast<const SSODescriptorType&>(*issuer),
- dynamic_cast<const X509TrustEngine*>(trustEngine)
- )
- );
-
- // Check Issuer of outer message.
- if (!issuerMatches(response->getIssuer(), provider->getEntityID())) {
- log.error("issuer of ArtifactResponse did not match source of artifact");
- throw BindingException("Issuer of ArtifactResponse did not match source of artifact.");
- }
-
- // Extract payload and check that Issuer.
- XMLObject* payload = response->getPayload();
- RequestAbstractType* req = NULL;
- StatusResponseType* res = dynamic_cast<StatusResponseType*>(payload);
- if (!res)
- req = dynamic_cast<RequestAbstractType*>(payload);
- if (!res && !req)
- throw BindingException("ArtifactResponse payload was not a recognized SAML 2.0 protocol message.");
-
- if (!issuerMatches(res ? res->getIssuer() : req->getIssuer(), provider->getEntityID())) {
- log.error("issuer of ArtifactResponse payload did not match source of artifact");
- throw BindingException("Issuer of ArtifactResponse payload did not match source of artifact.");
- }
-
- // Check payload freshness.
- time_t now = time(NULL);
- if ((res ? res->getIssueInstant() : req->getIssueInstant())->getEpoch() < now-(2*XMLToolingConfig::getConfig().clock_skew_secs))
- throw BindingException("Detected expired ArtifactResponse payload.");
-
- // Check replay.
- if (replayCache) {
- auto_ptr_char mid(res ? res->getID() : req->getID());
- if (!replayCache->check("SAML2ArtifactPayload", mid.get(), now + (2*XMLToolingConfig::getConfig().clock_skew_secs))) {
- log.error("replay detected of ArtifactResponse payload message ID (%s)", mid.get());
- throw BindingException("Rejecting replayed ArtifactResponse payload ($1).", params(1,mid.get()));
- }
- }
-
- // Check signatures.
- if (trustEngine) {
- if (response->getSignature()) {
- if (!trustEngine->validate(*(response->getSignature()), *issuer, metadataProvider->getKeyResolver())) {
- log.error("unable to verify signature on ArtifactResponse message with supplied trust engine");
- throw BindingException("Message signature failed verification.");
- }
- else if (!securityMech) {
- securityMech = samlconstants::SAML20P_NS;
- }
- }
- Signature* sig = (res ? res->getSignature() : req->getSignature());
- if (sig) {
- if (!trustEngine->validate(*sig, *issuer, metadataProvider->getKeyResolver())) {
- log.error("unable to verify signature on ArtifactResponse payload with supplied trust engine");
- throw BindingException("Message signature failed verification.");
- }
- else if (!securityMech) {
- securityMech = samlconstants::SAML20P_NS;
- }
- }
- }
-
- if (!securityMech) {
- log.warn("unable to authenticate ArtifactResponse message or payload, leaving untrusted");
- }
-
- // Return the payload only.
- response.release();
- payload->detach();
- return payload;
- }
- catch (XMLToolingException& ex) {
- annotateException(&ex,issuer,false);
- throw;
- }
-}
-
-bool SAML2ArtifactDecoder::issuerMatches(const Issuer* messageIssuer, const XMLCh* expectedIssuer) const
-{
- if (messageIssuer && messageIssuer->getName()) {
- if (messageIssuer->getFormat() && !XMLString::equals(messageIssuer->getFormat(), NameIDType::ENTITY))
- return false;
- else if (!XMLString::equals(expectedIssuer, messageIssuer->getName()))
- return false;
- }
- return true;
+ log.debug("calling ArtifactResolver...");
+ auto_ptr<ArtifactResponse> response(
+ m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast<const SSODescriptorType&>(*roledesc), policy)
+ );
+
+ // The policy should be enforced against the ArtifactResponse by the resolve step.
+ // Reset only the message state.
+ policy.reset(true);
+
+ // Extract payload and check that message.
+ XMLObject* payload = response->getPayload();
+ policy.evaluate(*payload, &genericRequest, samlconstants::SAML20P_NS);
+
+ // Return the payload only.
+ response.release();
+ payload->detach();
+ return payload;