+
+void SignatureMetadataFilter::doFilter(EntityDescriptor& entity, bool rootObject) const
+{
+ Signature* sig = entity.getSignature();
+ if (!sig && rootObject)
+ throw MetadataFilterException("Root metadata element was unsigned.");
+ verifySignature(sig, entity.getEntityID());
+
+ if (!m_verifyRoles)
+ return;
+
+ VectorOf(IDPSSODescriptor) idp = entity.getIDPSSODescriptors();
+ for (VectorOf(IDPSSODescriptor)::size_type i = 0; i < idp.size(); ) {
+ try {
+ verifySignature(idp[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out IDPSSODescriptor for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ idp.erase(idp.begin() + i);
+ }
+ }
+
+ VectorOf(SPSSODescriptor) sp = entity.getSPSSODescriptors();
+ for (VectorOf(SPSSODescriptor)::size_type i = 0; i < sp.size(); ) {
+ try {
+ verifySignature(sp[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out SPSSODescriptor for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ sp.erase(sp.begin() + i);
+ }
+ }
+
+ VectorOf(AuthnAuthorityDescriptor) authn = entity.getAuthnAuthorityDescriptors();
+ for (VectorOf(AuthnAuthorityDescriptor)::size_type i = 0; i < authn.size(); ) {
+ try {
+ verifySignature(authn[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out AuthnAuthorityDescriptor for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ authn.erase(authn.begin() + i);
+ }
+ }
+
+ VectorOf(AttributeAuthorityDescriptor) aa = entity.getAttributeAuthorityDescriptors();
+ for (VectorOf(AttributeAuthorityDescriptor)::size_type i = 0; i < aa.size(); ) {
+ try {
+ verifySignature(aa[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out AttributeAuthorityDescriptor for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ aa.erase(aa.begin() + i);
+ }
+ }
+
+ VectorOf(PDPDescriptor) pdp = entity.getPDPDescriptors();
+ for (VectorOf(AuthnAuthorityDescriptor)::size_type i = 0; i < pdp.size(); ) {
+ try {
+ verifySignature(pdp[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out PDPDescriptor for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ pdp.erase(pdp.begin() + i);
+ }
+ }
+
+ VectorOf(AuthnQueryDescriptorType) authnq = entity.getAuthnQueryDescriptorTypes();
+ for (VectorOf(AuthnQueryDescriptorType)::size_type i = 0; i < authnq.size(); ) {
+ try {
+ verifySignature(authnq[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out AuthnQueryDescriptorType for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ authnq.erase(authnq.begin() + i);
+ }
+ }
+
+ VectorOf(AttributeQueryDescriptorType) attrq = entity.getAttributeQueryDescriptorTypes();
+ for (VectorOf(AttributeQueryDescriptorType)::size_type i = 0; i < attrq.size(); ) {
+ try {
+ verifySignature(attrq[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out AttributeQueryDescriptorType for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ attrq.erase(attrq.begin() + i);
+ }
+ }
+
+ VectorOf(AuthzDecisionQueryDescriptorType) authzq = entity.getAuthzDecisionQueryDescriptorTypes();
+ for (VectorOf(AuthzDecisionQueryDescriptorType)::size_type i = 0; i < authzq.size(); ) {
+ try {
+ verifySignature(authzq[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out AuthzDecisionQueryDescriptorType for entity (%s) after failed signature check: %s", id.get(), e.what()
+ );
+ authzq.erase(authzq.begin() + i);
+ }
+ }
+
+ VectorOf(RoleDescriptor) v = entity.getRoleDescriptors();
+ for (VectorOf(RoleDescriptor)::size_type i = 0; i < v.size(); ) {
+ try {
+ verifySignature(v[i]->getSignature(), entity.getEntityID());
+ i++;
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn(
+ "filtering out role (%s) for entity (%s) after failed signature check: %s",
+ v[i]->getElementQName().toString().c_str(), id.get(), e.what()
+ );
+ v.erase(v.begin() + i);
+ }
+ }
+
+ if (entity.getAffiliationDescriptor()) {
+ try {
+ verifySignature(entity.getAffiliationDescriptor()->getSignature(), entity.getEntityID());
+ }
+ catch (exception& e) {
+ auto_ptr_char id(entity.getEntityID());
+ m_log.warn("filtering out affiliation from entity (%s) after failed signature check: %s", id.get(), e.what());
+ entity.setAffiliationDescriptor(nullptr);
+ }
+ }
+}
+
+void SignatureMetadataFilter::verifySignature(Signature* sig, const XMLCh* peerName) const
+{
+ if (!sig)
+ return;
+
+ m_profileValidator.validate(sig);
+
+ // Set up criteria.
+ CredentialCriteria cc;
+ cc.setUsage(Credential::SIGNING_CREDENTIAL);
+ cc.setSignature(*sig, CredentialCriteria::KEYINFO_EXTRACTION_KEY);
+
+ if (m_credResolver.get()) {
+ if (peerName) {
+ auto_ptr_char pname(peerName);
+ cc.setPeerName(pname.get());
+ }
+ Locker locker(m_credResolver.get());
+ vector<const Credential*> creds;
+ if (m_credResolver->resolve(creds,&cc)) {
+ SignatureValidator sigValidator;
+ for (vector<const Credential*>::const_iterator i = creds.begin(); i != creds.end(); ++i) {
+ try {
+ sigValidator.setCredential(*i);
+ sigValidator.validate(sig);
+ return; // success!
+ }
+ catch (exception&) {
+ }
+ }
+ throw MetadataFilterException("Unable to verify signature with supplied key(s).");
+ }
+ else {
+ throw MetadataFilterException("CredentialResolver did not supply any candidate keys.");
+ }
+ }
+ else if (m_trust.get()) {
+ if (m_verifyName && peerName) {
+ auto_ptr_char pname(peerName);
+ cc.setPeerName(pname.get());
+ }
+ if (m_trust->validate(*sig, *m_dummyResolver, &cc))
+ return;
+ throw MetadataFilterException("TrustEngine unable to verify signature.");
+ }
+
+ throw MetadataFilterException("Unable to verify signature.");
+}