44e9f4da445ba29bda805adce4cba42230b59f8e
[shibboleth/cpp-xmltooling.git] / xmltooling / security / CredentialCriteria.h
1 /*
2  *  Copyright 2001-2007 Internet2
3  * 
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /**
18  * @file xmltooling/security/CredentialCriteria.h
19  * 
20  * Class for specifying criteria by which a CredentialResolver should resolve credentials.
21  */
22
23 #if !defined(__xmltooling_credcrit_h__) && !defined(XMLTOOLING_NO_XMLSEC)
24 #define __xmltooling_credcrit_h__
25
26 #include <xmltooling/XMLToolingConfig.h>
27 #include <xmltooling/security/KeyInfoResolver.h>
28 #include <xmltooling/security/X509Credential.h>
29 #include <xmltooling/signature/KeyInfo.h>
30 #include <xmltooling/signature/Signature.h>
31
32 #include <set>
33 #include <xsec/dsig/DSIGKeyInfoList.hpp>
34 #include <xsec/dsig/DSIGKeyInfoName.hpp>
35
36 namespace xmltooling {
37
38     /**
39      * Class for specifying criteria by which a CredentialResolver should resolve credentials.
40      */
41     class XMLTOOL_API CredentialCriteria
42     {
43         MAKE_NONCOPYABLE(CredentialCriteria);
44     public:
45         CredentialCriteria() : m_keyUsage(UNSPECIFIED_CREDENTIAL), m_keySize(0), m_key(NULL),
46             m_keyInfo(NULL), m_nativeKeyInfo(NULL), m_credential(NULL) {
47         }
48         virtual ~CredentialCriteria() {
49             delete m_credential;
50         }
51
52         /**
53          * Determines whether the supplied Credential matches this CredentialCriteria.
54          *
55          * @param credential    the Credential to evaluate
56          * @return true iff the Credential is consistent with this criteria
57          */
58         virtual bool matches(const Credential& credential) const;
59
60         enum UsageType {
61             UNSPECIFIED_CREDENTIAL,
62             SIGNING_CREDENTIAL,
63             TLS_CREDENTIAL,
64             ENCRYPTION_CREDENTIAL
65         };
66         
67         /**
68          * Get the key usage criteria.
69          * 
70          * @return the usage.
71          */
72         UsageType getUsage() const {
73             return m_keyUsage;
74         }
75     
76         /**
77          * Set the key usage criteria.
78          * 
79          * @param usage the usage to set
80          */
81         void setUsage(UsageType usage) {
82             m_keyUsage = usage;
83         }
84
85         /**
86          * Get the peer name criteria.
87          * 
88          * @return the peer name
89          */
90         const char* getPeerName() const {
91             return m_peerName.c_str();
92         }
93     
94         /**
95          * Set the peer name criteria.
96          * 
97          * @param peerName peer name to set
98          */
99         void setPeerName(const char* peerName) {
100             m_peerName.erase();
101             if (peerName)
102                 m_peerName = peerName;
103         }
104     
105         /**
106          * Get the key algorithm criteria.
107          * 
108          * @return the key algorithm
109          */
110         const char* getKeyAlgorithm() const {
111             return m_keyAlgorithm.c_str();
112         }
113     
114         /**
115          * Set the key algorithm criteria.
116          * 
117          * @param keyAlgorithm The key algorithm to set
118          */
119         void setKeyAlgorithm(const char* keyAlgorithm) {
120             m_keyAlgorithm.erase();
121             if (keyAlgorithm)
122                 m_keyAlgorithm = keyAlgorithm;
123         }
124
125         /**
126          * Get the key size criteria.
127          *
128          * @return  the key size, or 0
129          */
130         unsigned int getKeySize() const {
131             return m_keySize;
132         }
133
134         /**
135          * Set the key size criteria.
136          *
137          * @param keySize Key size to set
138          */
139         void setKeySize(unsigned int keySize) {
140             m_keySize = keySize;
141         }
142     
143         /**
144          * Set the key algorithm and size criteria based on an XML algorithm specifier.
145          *
146          * @param algorithm XML algorithm specifier
147          */
148         void setXMLAlgorithm(const XMLCh* algorithm) {
149             if (algorithm) {
150                 std::pair<const char*,unsigned int> mapped =
151                     XMLToolingConfig::getConfig().mapXMLAlgorithmToKeyAlgorithm(algorithm);
152                 setKeyAlgorithm(mapped.first);
153                 setKeySize(mapped.second);
154             }
155             else {
156                 setKeyAlgorithm(NULL);
157                 setKeySize(0);
158             }
159         }
160
161         /**
162          * Gets key name criteria.
163          * 
164          * @return an immutable set of key names
165          */
166         const std::set<std::string>& getKeyNames() const {
167             return m_keyNames;
168         }
169
170         /**
171          * Gets key name criteria.
172          * 
173          * @return a mutable set of key names
174          */
175         std::set<std::string>& getKeyNames() {
176             return m_keyNames;
177         }
178
179         /**
180          * Returns the public key criteria.
181          * 
182          * @return  a public key
183          */
184         virtual XSECCryptoKey* getPublicKey() const {
185             return m_key;
186         }
187
188         /**
189          * Sets the public key criteria.
190          *
191          * <p>The lifetime of the key <strong>MUST</strong> extend
192          * for the lifetime of this object.
193          * 
194          * @param key a public key
195          */
196         void setPublicKey(XSECCryptoKey* key) {
197             m_key = key;
198         }
199
200         enum keyinfo_extraction_t {
201             KEYINFO_EXTRACTION_KEY = 1,
202             KEYINFO_EXTRACTION_KEYNAMES = 2,
203             KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES = 4
204         };
205
206         /**
207          * Gets the KeyInfo criteria.
208          * 
209          * @return the KeyInfo criteria
210          */
211         const xmlsignature::KeyInfo* getKeyInfo() const {
212             return m_keyInfo;
213         }
214     
215         /**
216          * Sets the KeyInfo criteria.
217          * 
218          * @param keyInfo       the KeyInfo criteria
219          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
220          */
221         virtual void setKeyInfo(const xmlsignature::KeyInfo* keyInfo, int extraction=0) {
222             delete m_credential;
223             m_credential = NULL;
224             m_keyInfo = keyInfo;
225             if (!keyInfo || !extraction)
226                 return;
227
228             int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
229             types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
230             m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
231
232             if (extraction & KEYINFO_EXTRACTION_KEY)
233                 setPublicKey(m_credential->getPublicKey());
234             if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
235                 m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
236             if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
237                 const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
238                 if (xcred && !xcred->getEntityCertificateChain().empty())
239                     X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
240             }
241         } 
242
243         /**
244          * Gets the native KeyInfo criteria.
245          * 
246          * @return the native KeyInfo criteria
247          */
248         DSIGKeyInfoList* getNativeKeyInfo() const {
249             return m_nativeKeyInfo;
250         }
251
252         /**
253          * Sets the KeyInfo criteria.
254          * 
255          * @param keyInfo       the KeyInfo criteria
256          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
257          */
258         virtual void setNativeKeyInfo(DSIGKeyInfoList* keyInfo, int extraction=0) {
259             delete m_credential;
260             m_credential = NULL;
261             m_nativeKeyInfo = keyInfo;
262             if (!keyInfo || !extraction)
263                 return;
264
265             int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
266             types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
267             m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
268
269             if (extraction & KEYINFO_EXTRACTION_KEY)
270                 setPublicKey(m_credential->getPublicKey());
271             if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
272                 m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
273             if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
274                 const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
275                 if (xcred && !xcred->getEntityCertificateChain().empty())
276                     X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
277             }
278         }
279
280         /**
281          * Sets the KeyInfo criteria from an XML Signature.
282          * 
283          * @param sig           the Signature containing KeyInfo criteria
284          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
285          */
286         void setSignature(const xmlsignature::Signature& sig, int extraction=0) {
287             setXMLAlgorithm(sig.getSignatureAlgorithm());
288             xmlsignature::KeyInfo* k = sig.getKeyInfo();
289             if (k)
290                 return setKeyInfo(k,extraction);
291             DSIGSignature* dsig = sig.getXMLSignature();
292             if (dsig)
293                 setNativeKeyInfo(dsig->getKeyInfoList(),extraction);
294         }
295
296     private:
297         UsageType m_keyUsage;
298         unsigned int m_keySize;
299         std::string m_peerName,m_keyAlgorithm;
300         std::set<std::string> m_keyNames;
301         XSECCryptoKey* m_key;
302         const xmlsignature::KeyInfo* m_keyInfo;
303         DSIGKeyInfoList* m_nativeKeyInfo;
304         Credential* m_credential;
305     };
306 };
307
308 #endif /* __xmltooling_credcrit_h__ */