2 * Copyright 2001-2007 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * SignatureMetadataFilter.cpp
20 * Filters out unsigned or mis-signed elements.
24 #include "saml2/metadata/Metadata.h"
25 #include "saml2/metadata/MetadataFilter.h"
26 #include "signature/SignatureProfileValidator.h"
28 #include <log4cpp/Category.hh>
30 #include <xmltooling/util/NDC.h>
31 #include <xmltooling/signature/SignatureValidator.h>
33 using namespace opensaml::saml2md;
34 using namespace opensaml;
35 using namespace xmlsignature;
36 using namespace xmltooling;
37 using namespace log4cpp;
43 class SAML_DLLLOCAL SignatureMetadataFilter : public MetadataFilter
46 SignatureMetadataFilter(const DOMElement* e);
47 ~SignatureMetadataFilter() {
48 delete m_sigValidator;
51 const char* getId() const { return SIGNATURE_METADATA_FILTER; }
52 void doFilter(XMLObject& xmlObject) const;
55 void doFilter(EntitiesDescriptor& entities, bool rootObject=false) const;
56 void verifySignature(Signature* sig) const {
58 m_profileValidator.validate(sig);
59 m_sigValidator->validate(sig);
63 SignatureProfileValidator m_profileValidator;
64 SignatureValidator* m_sigValidator;
67 MetadataFilter* SAML_DLLLOCAL SignatureMetadataFilterFactory(const DOMElement* const & e)
69 return new SignatureMetadataFilter(e);
75 static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r);
76 static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e);
78 SignatureMetadataFilter::SignatureMetadataFilter(const DOMElement* e) : m_sigValidator(NULL)
80 e = XMLHelper::getFirstChildElement(e, GenericKeyResolver);
81 auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL);
83 auto_ptr<KeyResolver> kr(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e));
84 m_sigValidator = new SignatureValidator(kr.get());
88 throw MetadataFilterException("missing <KeyResolver> element, or no type attribute found");
91 void SignatureMetadataFilter::doFilter(XMLObject& xmlObject) const
98 EntitiesDescriptor& entities = dynamic_cast<EntitiesDescriptor&>(xmlObject);
99 doFilter(entities, true);
106 EntityDescriptor& entity = dynamic_cast<EntityDescriptor&>(xmlObject);
107 if (!entity.getSignature())
108 throw MetadataFilterException("Root metadata element was unsigned.");
109 verifySignature(entity.getSignature());
114 throw MetadataFilterException("SignatureMetadataFilter was given an improper metadata instance to filter.");
117 void SignatureMetadataFilter::doFilter(EntitiesDescriptor& entities, bool rootObject) const
119 Category& log=Category::getInstance(SAML_LOGCAT".Metadata");
121 Signature* sig = entities.getSignature();
122 if (!sig && rootObject)
123 throw MetadataFilterException("Root metadata element was unsigned.");
124 verifySignature(sig);
126 VectorOf(EntityDescriptor) v=entities.getEntityDescriptors();
127 for (VectorOf(EntityDescriptor)::size_type i=0; i<v.size(); ) {
129 verifySignature(v[i]->getSignature());
132 catch (XMLToolingException& e) {
133 auto_ptr_char id(v[i]->getEntityID());
134 log.info("filtering out entity (%s) after failed signature check: ", id.get(), e.what());
135 v.erase(v.begin() + i);
139 VectorOf(EntitiesDescriptor) w=entities.getEntitiesDescriptors();
140 for (VectorOf(EntitiesDescriptor)::size_type j=0; j<w.size(); ) {
142 verifySignature(w[j]->getSignature());
145 catch (XMLToolingException& e) {
146 auto_ptr_char name(w[j]->getName());
147 log.info("filtering out group (%s) after failed signature check: ", name.get(), e.what());
148 w.erase(w.begin() + j);