2 * Copyright 2009 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 * KeyDescriptorAttributeExtractor.cpp
20 * AttributeExtractor for KeyDescriptor information.
24 #include "exceptions.h"
25 #include "Application.h"
26 #include "attribute/AttributeDecoder.h"
27 #include "attribute/SimpleAttribute.h"
28 #include "attribute/resolver/AttributeExtractor.h"
30 #include <saml/saml2/metadata/Metadata.h>
31 #include <saml/saml2/metadata/MetadataCredentialCriteria.h>
32 #include <saml/saml2/metadata/MetadataProvider.h>
33 #include <xmltooling/security/Credential.h>
34 #include <xmltooling/security/SecurityHelper.h>
35 #include <xmltooling/util/XMLHelper.h>
36 #include <xercesc/util/XMLUniDefs.hpp>
38 using namespace shibsp;
39 using namespace opensaml::saml2md;
40 using namespace opensaml;
41 using namespace xmltooling;
46 #if defined (_MSC_VER)
47 #pragma warning( push )
48 #pragma warning( disable : 4250 )
51 class KeyDescriptorExtractor : public AttributeExtractor
54 KeyDescriptorExtractor(const DOMElement* e);
55 ~KeyDescriptorExtractor() {}
64 void extractAttributes(
65 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
68 void getAttributeIds(std::vector<std::string>& attributes) const {
69 if (!m_hashId.empty())
70 attributes.push_back(m_hashId.front());
71 if (!m_signingId.empty())
72 attributes.push_back(m_signingId.front());
73 if (!m_encryptionId.empty())
74 attributes.push_back(m_encryptionId.front());
78 auto_ptr_char m_hashAlg;
79 vector<string> m_hashId;
80 vector<string> m_signingId;
81 vector<string> m_encryptionId;
84 #if defined (_MSC_VER)
85 #pragma warning( pop )
88 AttributeExtractor* SHIBSP_DLLLOCAL KeyDescriptorAttributeExtractorFactory(const DOMElement* const & e)
90 return new KeyDescriptorExtractor(e);
93 static const XMLCh encryptionId[] = UNICODE_LITERAL_12(e,n,c,r,y,p,t,i,o,n,I,d);
94 static const XMLCh hashId[] = UNICODE_LITERAL_6(h,a,s,h,I,d);
95 static const XMLCh hashAlg[] = UNICODE_LITERAL_7(h,a,s,h,A,l,g);
96 static const XMLCh signingId[] = UNICODE_LITERAL_9(s,i,g,n,i,n,g,I,d);
99 KeyDescriptorExtractor::KeyDescriptorExtractor(const DOMElement* e) : m_hashAlg(e ? e->getAttributeNS(NULL, hashAlg) : NULL)
102 const XMLCh* a = e->getAttributeNS(NULL, hashId);
104 auto_ptr_char temp(a);
105 m_hashId.push_back(temp.get());
107 a = e->getAttributeNS(NULL, signingId);
109 auto_ptr_char temp(a);
110 m_signingId.push_back(temp.get());
112 a = e->getAttributeNS(NULL, encryptionId);
114 auto_ptr_char temp(a);
115 m_encryptionId.push_back(temp.get());
118 if (m_hashId.empty() && m_signingId.empty() && m_encryptionId.empty())
119 throw ConfigurationException("KeyDescriptor AttributeExtractor requires hashId, signingId, or encryptionId property.");
122 void KeyDescriptorExtractor::extractAttributes(
123 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
126 const RoleDescriptor* role = dynamic_cast<const RoleDescriptor*>(&xmlObject);
130 vector<const Credential*> creds;
131 MetadataCredentialCriteria mcc(*role);
133 if (!m_signingId.empty() || !m_hashId.empty()) {
134 mcc.setUsage(Credential::SIGNING_CREDENTIAL);
135 if (application.getMetadataProvider()->resolve(creds, &mcc)) {
136 if (!m_hashId.empty()) {
137 const char* alg = m_hashAlg.get();
140 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_hashId));
141 vector<string>& vals = attr->getValues();
142 for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
143 if (vals.empty() || !vals.back().empty())
144 vals.push_back(string());
145 vals.back() = SecurityHelper::getDEREncoding(*(*c), alg);
147 if (vals.back().empty())
150 attributes.push_back(attr.release());
152 if (!m_signingId.empty()) {
153 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_signingId));
154 vector<string>& vals = attr->getValues();
155 for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
156 if (vals.empty() || !vals.back().empty())
157 vals.push_back(string());
158 vals.back() = SecurityHelper::getDEREncoding(*(*c));
160 if (vals.back().empty())
163 attributes.push_back(attr.release());
169 if (!m_encryptionId.empty()) {
170 mcc.setUsage(Credential::ENCRYPTION_CREDENTIAL);
171 if (application.getMetadataProvider()->resolve(creds, &mcc)) {
172 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_encryptionId));
173 vector<string>& vals = attr->getValues();
174 for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
175 if (vals.empty() || !vals.back().empty())
176 vals.push_back(string());
177 vals.back() = SecurityHelper::getDEREncoding(*(*c));
179 if (vals.back().empty())
182 attributes.push_back(attr.release());