d331c897063297a060d544d7322dff67d84710df
[shibboleth/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         /**
61          * Enumeration of use cases for credentials. 
62          */
63         enum UsageType {
64             UNSPECIFIED_CREDENTIAL,
65             SIGNING_CREDENTIAL,
66             TLS_CREDENTIAL,
67             ENCRYPTION_CREDENTIAL
68         };
69         
70         /**
71          * Get the key usage criteria.
72          * 
73          * @return the usage.
74          */
75         UsageType getUsage() const {
76             return m_keyUsage;
77         }
78     
79         /**
80          * Set the key usage criteria.
81          * 
82          * @param usage the usage to set
83          */
84         void setUsage(UsageType usage) {
85             m_keyUsage = usage;
86         }
87
88         /**
89          * Get the peer name criteria.
90          * 
91          * @return the peer name
92          */
93         const char* getPeerName() const {
94             return m_peerName.c_str();
95         }
96     
97         /**
98          * Set the peer name criteria.
99          * 
100          * @param peerName peer name to set
101          */
102         void setPeerName(const char* peerName) {
103             m_peerName.erase();
104             if (peerName)
105                 m_peerName = peerName;
106         }
107     
108         /**
109          * Get the key algorithm criteria.
110          * 
111          * @return the key algorithm
112          */
113         const char* getKeyAlgorithm() const {
114             return m_keyAlgorithm.c_str();
115         }
116     
117         /**
118          * Set the key algorithm criteria.
119          * 
120          * @param keyAlgorithm The key algorithm to set
121          */
122         void setKeyAlgorithm(const char* keyAlgorithm) {
123             m_keyAlgorithm.erase();
124             if (keyAlgorithm)
125                 m_keyAlgorithm = keyAlgorithm;
126         }
127
128         /**
129          * Get the key size criteria.
130          *
131          * @return  the key size, or 0
132          */
133         unsigned int getKeySize() const {
134             return m_keySize;
135         }
136
137         /**
138          * Set the key size criteria.
139          *
140          * @param keySize Key size to set
141          */
142         void setKeySize(unsigned int keySize) {
143             m_keySize = keySize;
144         }
145     
146         /**
147          * Set the key algorithm and size criteria based on an XML algorithm specifier.
148          *
149          * @param algorithm XML algorithm specifier
150          */
151         void setXMLAlgorithm(const XMLCh* algorithm) {
152             if (algorithm) {
153                 std::pair<const char*,unsigned int> mapped =
154                     XMLToolingConfig::getConfig().mapXMLAlgorithmToKeyAlgorithm(algorithm);
155                 setKeyAlgorithm(mapped.first);
156                 setKeySize(mapped.second);
157             }
158             else {
159                 setKeyAlgorithm(NULL);
160                 setKeySize(0);
161             }
162         }
163
164         /**
165          * Gets key name criteria.
166          * 
167          * @return an immutable set of key names
168          */
169         const std::set<std::string>& getKeyNames() const {
170             return m_keyNames;
171         }
172
173         /**
174          * Gets key name criteria.
175          * 
176          * @return a mutable set of key names
177          */
178         std::set<std::string>& getKeyNames() {
179             return m_keyNames;
180         }
181
182         /**
183          * Returns the public key criteria.
184          * 
185          * @return  a public key
186          */
187         virtual XSECCryptoKey* getPublicKey() const {
188             return m_key;
189         }
190
191         /**
192          * Sets the public key criteria.
193          *
194          * <p>The lifetime of the key <strong>MUST</strong> extend
195          * for the lifetime of this object.
196          * 
197          * @param key a public key
198          */
199         void setPublicKey(XSECCryptoKey* key) {
200             m_key = key;
201         }
202
203         /**
204          * Bitmask constants controlling the kinds of criteria set automatically
205          * based on a KeyInfo object.
206          */
207         enum keyinfo_extraction_t {
208             KEYINFO_EXTRACTION_KEY = 1,
209             KEYINFO_EXTRACTION_KEYNAMES = 2,
210             KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES = 4
211         };
212
213         /**
214          * Gets the KeyInfo criteria.
215          * 
216          * @return the KeyInfo criteria
217          */
218         const xmlsignature::KeyInfo* getKeyInfo() const {
219             return m_keyInfo;
220         }
221     
222         /**
223          * Sets the KeyInfo criteria.
224          * 
225          * @param keyInfo       the KeyInfo criteria
226          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
227          */
228         virtual void setKeyInfo(const xmlsignature::KeyInfo* keyInfo, int extraction=0) {
229             delete m_credential;
230             m_credential = NULL;
231             m_keyInfo = keyInfo;
232             if (!keyInfo || !extraction)
233                 return;
234
235             int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
236             types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
237             m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
238
239             if (extraction & KEYINFO_EXTRACTION_KEY)
240                 setPublicKey(m_credential->getPublicKey());
241             if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
242                 m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
243             if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
244                 const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
245                 if (xcred && !xcred->getEntityCertificateChain().empty())
246                     X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
247             }
248         } 
249
250         /**
251          * Gets the native KeyInfo criteria.
252          * 
253          * @return the native KeyInfo criteria
254          */
255         DSIGKeyInfoList* getNativeKeyInfo() const {
256             return m_nativeKeyInfo;
257         }
258
259         /**
260          * Sets the KeyInfo criteria.
261          * 
262          * @param keyInfo       the KeyInfo criteria
263          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
264          */
265         virtual void setNativeKeyInfo(DSIGKeyInfoList* keyInfo, int extraction=0) {
266             delete m_credential;
267             m_credential = NULL;
268             m_nativeKeyInfo = keyInfo;
269             if (!keyInfo || !extraction)
270                 return;
271
272             int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
273             types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
274             m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
275
276             if (extraction & KEYINFO_EXTRACTION_KEY)
277                 setPublicKey(m_credential->getPublicKey());
278             if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
279                 m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
280             if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
281                 const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
282                 if (xcred && !xcred->getEntityCertificateChain().empty())
283                     X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
284             }
285         }
286
287         /**
288          * Sets the KeyInfo criteria from an XML Signature.
289          * 
290          * @param sig           the Signature containing KeyInfo criteria
291          * @param extraction    bitmask of criteria to auto-extract from KeyInfo
292          */
293         void setSignature(const xmlsignature::Signature& sig, int extraction=0) {
294             setXMLAlgorithm(sig.getSignatureAlgorithm());
295             xmlsignature::KeyInfo* k = sig.getKeyInfo();
296             if (k)
297                 return setKeyInfo(k,extraction);
298             DSIGSignature* dsig = sig.getXMLSignature();
299             if (dsig)
300                 setNativeKeyInfo(dsig->getKeyInfoList(),extraction);
301         }
302
303     private:
304         UsageType m_keyUsage;
305         unsigned int m_keySize;
306         std::string m_peerName,m_keyAlgorithm;
307         std::set<std::string> m_keyNames;
308         XSECCryptoKey* m_key;
309         const xmlsignature::KeyInfo* m_keyInfo;
310         DSIGKeyInfoList* m_nativeKeyInfo;
311         Credential* m_credential;
312     };
313 };
314
315 #endif /* __xmltooling_credcrit_h__ */