Add XML-based client SSL config.
[shibboleth/cpp-sp.git] / shib / shib.h
1 /*
2  * The Shibboleth License, Version 1.
3  * Copyright (c) 2002
4  * University Corporation for Advanced Internet Development, Inc.
5  * All rights reserved
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution, if any, must include
17  * the following acknowledgment: "This product includes software developed by
18  * the University Corporation for Advanced Internet Development
19  * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20  * may appear in the software itself, if and wherever such third-party
21  * acknowledgments normally appear.
22  *
23  * Neither the name of Shibboleth nor the names of its contributors, nor
24  * Internet2, nor the University Corporation for Advanced Internet Development,
25  * Inc., nor UCAID may be used to endorse or promote products derived from this
26  * software without specific prior written permission. For written permission,
27  * please contact shibboleth@shibboleth.org
28  *
29  * Products derived from this software may not be called Shibboleth, Internet2,
30  * UCAID, or the University Corporation for Advanced Internet Development, nor
31  * may Shibboleth appear in their name, without prior written permission of the
32  * University Corporation for Advanced Internet Development.
33  *
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36  * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39  * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40  * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41  * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49
50
51 /* shib.h - Shibboleth header file
52
53    Scott Cantor
54    6/4/02
55
56    $History:$
57 */
58
59 #ifndef __shib_h__
60 #define __shib_h__
61
62 #include <saml/saml.h>
63 #include <openssl/ssl.h>
64
65 #ifdef WIN32
66 # ifndef SHIB_EXPORTS
67 #  define SHIB_EXPORTS __declspec(dllimport)
68 # endif
69 #else
70 # define SHIB_EXPORTS
71 #endif
72
73 #define SHIB_L(s) shibboleth::XML::Literals::s
74 #define SHIB_L_QNAME(p,s) shibboleth::XML::Literals::p##_##s
75
76 namespace shibboleth
77 {
78     #define DECLARE_SHIB_EXCEPTION(name,base) \
79         class SHIB_EXPORTS name : public saml::base \
80         { \
81         public: \
82             name(const char* msg) : saml::base(msg) {RTTI(name);} \
83             name(const std::string& msg) : saml::base(msg) {RTTI(name);} \
84             name(const saml::Iterator<saml::QName>& codes, const char* msg) : saml::base(codes,msg) {RTTI(name);} \
85             name(const saml::Iterator<saml::QName>& codes, const std::string& msg) : saml::base(codes, msg) {RTTI(name);} \
86             name(const saml::QName& code, const char* msg) : saml::base(code,msg) {RTTI(name);} \
87             name(const saml::QName& code, const std::string& msg) : saml::base(code, msg) {RTTI(name);} \
88             name(DOMElement* e) : saml::base(e) {RTTI(name);} \
89             name(std::istream& in) : saml::base(in) {RTTI(name);} \
90             virtual ~name() throw () {} \
91         }
92
93     DECLARE_SHIB_EXCEPTION(UnsupportedProtocolException,SAMLException);
94     DECLARE_SHIB_EXCEPTION(MetadataException,SAMLException);
95
96     // Metadata abstract interfaces
97     
98     struct SHIB_EXPORTS IContactInfo
99     {
100         enum ContactType { technical, administrative, billing, other };
101         virtual ContactType getType() const=0;
102         virtual const char* getName() const=0;
103         virtual const char* getEmail() const=0;
104         virtual ~IContactInfo() {}
105     };
106
107     struct SHIB_EXPORTS ISite
108     {
109         virtual const XMLCh* getName() const=0;
110         virtual saml::Iterator<const XMLCh*> getGroups() const=0;
111         virtual saml::Iterator<const IContactInfo*> getContacts() const=0;
112         virtual const char* getErrorURL() const=0;
113         virtual bool validate(saml::Iterator<XSECCryptoX509*> certs) const=0;
114         virtual bool validate(saml::Iterator<const XMLCh*> certs) const=0;
115         virtual ~ISite() {}
116     };
117     
118     struct SHIB_EXPORTS IAuthority
119     {
120         virtual const XMLCh* getName() const=0;
121         virtual const char* getURL() const=0;
122         virtual ~IAuthority() {}
123     };
124
125     struct SHIB_EXPORTS IOriginSite : public ISite
126     {
127         virtual saml::Iterator<const IAuthority*> getHandleServices() const=0;
128         virtual saml::Iterator<const IAuthority*> getAttributeAuthorities() const=0;
129         virtual saml::Iterator<std::pair<const XMLCh*,bool> > getSecurityDomains() const=0;
130         virtual ~IOriginSite() {}
131     };
132
133     struct SHIB_EXPORTS IMetadata
134     {
135         virtual void lock()=0;
136         virtual void unlock()=0;
137         virtual const ISite* lookup(const XMLCh* site) const=0;
138         virtual ~IMetadata() {}
139     };
140
141     struct SHIB_EXPORTS ITrust
142     {
143         virtual void lock()=0;
144         virtual void unlock()=0;
145         virtual saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject) const=0;
146         virtual bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const=0;
147         virtual bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const=0;
148         virtual bool attach(const ISite* site, SSL_CTX* ctx) const=0;
149         virtual ~ITrust() {}
150     };
151     
152     struct SHIB_EXPORTS ICredentials
153     {
154         virtual void lock()=0;
155         virtual void unlock()=0;
156         virtual bool attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx) const=0;
157         virtual ~ICredentials() {}
158     };
159     
160     struct SHIB_EXPORTS IAttributeRule
161     {
162         virtual const XMLCh* getName() const=0;
163         virtual const XMLCh* getNamespace() const=0;
164         virtual const char* getFactory() const=0;
165         virtual const char* getAlias() const=0;
166         virtual const char* getHeader() const=0;
167         virtual bool accept(const XMLCh* originSite, const DOMElement* e) const=0;
168         virtual ~IAttributeRule() {}
169     };
170     
171     struct SHIB_EXPORTS IAAP
172     {
173         virtual void lock()=0;
174         virtual void unlock()=0;
175         virtual const IAttributeRule* lookup(const XMLCh* attrName, const XMLCh* attrNamespace=NULL) const=0;
176         virtual const IAttributeRule* lookup(const char* alias) const=0;
177         virtual saml::Iterator<const IAttributeRule*> getAttributeRules() const=0;
178         virtual ~IAAP() {}
179     };
180
181 #ifdef SHIB_INSTANTIATE
182     template class SHIB_EXPORTS saml::Iterator<const IContactInfo*>;
183     template class SHIB_EXPORTS saml::ArrayIterator<const IContactInfo*>;
184     template class SHIB_EXPORTS saml::Iterator<const IAuthority*>;
185     template class SHIB_EXPORTS saml::ArrayIterator<const IAuthority*>;
186     template class SHIB_EXPORTS saml::Iterator<const IAttributeRule*>;
187     template class SHIB_EXPORTS saml::ArrayIterator<const IAttributeRule*>;
188     template class SHIB_EXPORTS saml::Iterator<IMetadata*>;
189     template class SHIB_EXPORTS saml::ArrayIterator<IMetadata*>;
190     template class SHIB_EXPORTS saml::Iterator<ITrust*>;
191     template class SHIB_EXPORTS saml::ArrayIterator<ITrust*>;
192     template class SHIB_EXPORTS saml::Iterator<ICredentials*>;
193     template class SHIB_EXPORTS saml::ArrayIterator<ICredentials*>;
194     template class SHIB_EXPORTS saml::Iterator<IAAP*>;
195     template class SHIB_EXPORTS saml::ArrayIterator<IAAP*>;
196 #endif
197
198     class SHIB_EXPORTS SimpleAttribute : public saml::SAMLAttribute
199     {
200     public:
201         SimpleAttribute(const XMLCh* name, const XMLCh* ns, long lifetime=0,
202                         const saml::Iterator<const XMLCh*>& values=EMPTY(const XMLCh*));
203         SimpleAttribute(DOMElement* e);
204         virtual saml::SAMLObject* clone() const;
205         virtual ~SimpleAttribute();
206
207     protected:
208         virtual bool accept(DOMElement* e) const;
209
210         const XMLCh* m_originSite;
211     };
212
213     class SHIB_EXPORTS ScopedAttribute : public SimpleAttribute
214     {
215     public:
216         ScopedAttribute(const XMLCh* name, const XMLCh* ns, long lifetime=0,
217                         const saml::Iterator<const XMLCh*>& scopes=EMPTY(const XMLCh*),
218                         const saml::Iterator<const XMLCh*>& values=EMPTY(const XMLCh*));
219         ScopedAttribute(DOMElement* e);
220         virtual ~ScopedAttribute();
221
222         virtual DOMNode* toDOM(DOMDocument* doc=NULL, bool xmlns=true) const;
223         virtual saml::SAMLObject* clone() const;
224
225         virtual saml::Iterator<const XMLCh*> getValues() const;
226         virtual saml::Iterator<std::string> getSingleByteValues() const;
227
228     protected:
229         virtual bool addValue(DOMElement* e);
230
231         std::vector<const XMLCh*> m_scopes;
232         mutable std::vector<const XMLCh*> m_scopedValues;
233     };
234
235     class SHIB_EXPORTS ShibPOSTProfile
236     {
237     public:
238         ShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* receiver, int ttlSeconds);
239         ShibPOSTProfile(const saml::Iterator<const XMLCh*>& policies, const XMLCh* issuer);
240         virtual ~ShibPOSTProfile();
241
242         virtual const saml::SAMLAssertion* getSSOAssertion(const saml::SAMLResponse& r);
243         virtual const saml::SAMLAuthenticationStatement* getSSOStatement(const saml::SAMLAssertion& a);
244         virtual saml::SAMLResponse* accept(const XMLByte* buf, XMLCh** originSitePtr=NULL);
245         virtual saml::SAMLResponse* prepare(
246             const XMLCh* recipient,
247             const XMLCh* name,
248             const XMLCh* nameQualifier,
249             const XMLCh* subjectIP,
250             const XMLCh* authMethod,
251             time_t authInstant,
252             const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings,
253             XSECCryptoKey* responseKey,
254             const saml::Iterator<XSECCryptoX509*>& responseCerts=EMPTY(XSECCryptoX509*),
255             XSECCryptoKey* assertionKey=NULL,
256             const saml::Iterator<XSECCryptoX509*>& assertionCerts=EMPTY(XSECCryptoX509*)
257             );
258         virtual bool checkReplayCache(const saml::SAMLAssertion& a);
259
260         virtual const XMLCh* getOriginSite(const saml::SAMLResponse& r);
261
262     protected:
263         virtual void verifySignature(
264             const saml::SAMLSignedObject& obj,
265             const IOriginSite* originSite,
266             const XMLCh* signerName,
267             XSECCryptoKey* knownKey=NULL);
268
269         signatureMethod m_algorithm;
270         std::vector<const XMLCh*> m_policies;
271         XMLCh* m_issuer;
272         XMLCh* m_receiver;
273         int m_ttlSeconds;
274
275     private:
276         ShibPOSTProfile(const ShibPOSTProfile&) {}
277         ShibPOSTProfile& operator=(const ShibPOSTProfile&) {return *this;}
278     };
279
280     class SHIB_EXPORTS ShibPOSTProfileFactory
281     {
282     public:
283         static ShibPOSTProfile* getInstance(const saml::Iterator<const XMLCh*>& policies, const XMLCh* receiver, int ttlSeconds);
284         static ShibPOSTProfile* getInstance(const saml::Iterator<const XMLCh*>& policies, const XMLCh* issuer);
285     };
286
287     // Glue classes between abstract metadata and concrete providers
288     
289     class SHIB_EXPORTS OriginMetadata
290     {
291     public:
292         OriginMetadata(const XMLCh* site);
293         ~OriginMetadata();
294         bool fail() const {return m_mapper==NULL;}
295         const IOriginSite* operator->() const {return m_site;}
296         operator const IOriginSite*() const {return m_site;}
297         
298     private:
299         OriginMetadata(const OriginMetadata&);
300         void operator=(const OriginMetadata&);
301         IMetadata* m_mapper;
302         const IOriginSite* m_site;
303     };
304
305     class SHIB_EXPORTS Trust
306     {
307     public:
308         Trust() : m_mapper(NULL) {}
309         ~Trust();
310         saml::Iterator<XSECCryptoX509*> getCertificates(const XMLCh* subject);
311         bool validate(const ISite* site, saml::Iterator<XSECCryptoX509*> certs) const;
312         bool validate(const ISite* site, saml::Iterator<const XMLCh*> certs) const;
313         bool attach(const ISite* site, SSL_CTX* ctx) const;
314         
315     private:
316         Trust(const Trust&);
317         void operator=(const Trust&);
318         ITrust* m_mapper;
319     };
320     
321     class SHIB_EXPORTS Credentials
322     {
323     public:
324         static bool attach(const XMLCh* subject, const ISite* relyingParty, SSL_CTX* ctx);
325     };
326
327     class SHIB_EXPORTS AAP
328     {
329     public:
330         AAP(const XMLCh* attrName, const XMLCh* attrNamespace=NULL);
331         AAP(const char* alias);
332         ~AAP();
333         bool fail() const {return m_mapper==NULL;}
334         const IAttributeRule* operator->() const {return m_rule;}
335         operator const IAttributeRule*() const {return m_rule;}
336         
337     private:
338         AAP(const AAP&);
339         void operator=(const AAP&);
340         IAAP* m_mapper;
341         const IAttributeRule* m_rule;
342     };
343
344     extern "C" { typedef IMetadata* MetadataFactory(const char* source); }
345     extern "C" { typedef ITrust* TrustFactory(const char* source); }
346     extern "C" { typedef ICredentials* CredentialsFactory(const char* source); }
347     extern "C" { typedef IAAP* AAPFactory(const char* source); }
348     
349     class SHIB_EXPORTS ShibConfig
350     {
351     public:
352         ShibConfig() {}
353         virtual ~ShibConfig();
354
355         // global per-process setup and shutdown of Shibboleth runtime
356         virtual bool init()=0;
357         virtual void term()=0;
358
359         // enables runtime and clients to access configuration
360         static ShibConfig& getConfig();
361
362         // allows pluggable implementations of metadata
363         virtual void regFactory(const char* type, MetadataFactory* factory)=0;
364         virtual void regFactory(const char* type, TrustFactory* factory)=0;
365         virtual void regFactory(const char* type, CredentialsFactory* factory)=0;
366         virtual void regFactory(const char* type, AAPFactory* factory)=0;
367         virtual void regFactory(const char* type, saml::SAMLAttributeFactory* factory)=0;
368         virtual void unregFactory(const char* type)=0;
369         
370         // builds a specific metadata lookup object
371         virtual bool addMetadata(const char* type, const char* source)=0;
372         
373         virtual saml::Iterator<IMetadata*> getMetadataProviders() const=0;
374         virtual saml::Iterator<ITrust*> getTrustProviders() const=0;
375         virtual saml::Iterator<ICredentials*> getCredentialProviders() const=0;
376         virtual saml::Iterator<IAAP*> getAAPProviders() const=0;
377         virtual saml::SAMLAttributeFactory* getAttributeFactory(const char* type) const=0;
378     };
379
380     struct SHIB_EXPORTS Constants
381     {
382         static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[];
383         static const XMLCh SHIB_NAMEID_FORMAT_URI[];
384         
385         static const XMLCh XMLSIG_RETMETHOD_RAWX509[];  // DER X.509 defined by xmlsig
386         static const XMLCh SHIB_RETMETHOD_PEMX509[];    // PEM cert chain
387         static const XMLCh SHIB_RETMETHOD_DERRSA[];     // PKCS1/DER RSA private key
388         static const XMLCh SHIB_RETMETHOD_PEMRSA[];     // PEM RSA private key
389         
390         static saml::QName SHIB_ATTRIBUTE_VALUE_TYPE; 
391     };
392
393     class SHIB_EXPORTS XML
394     {
395     public:
396         // URI constants
397         static const XMLCh SHIB_NS[];
398         static const XMLCh SHIB_SCHEMA_ID[];
399
400         struct SHIB_EXPORTS Literals
401         {
402             // Shibboleth vocabulary
403             static const XMLCh AttributeValueType[];
404
405             static const XMLCh Scope[];
406
407             static const XMLCh AttributeAuthority[];
408             static const XMLCh Contact[];
409             static const XMLCh Domain[];
410             static const XMLCh Email[];
411             static const XMLCh ErrorURL[];
412             static const XMLCh HandleService[];
413             static const XMLCh InvalidHandle[];
414             static const XMLCh Location[];
415             static const XMLCh Name[];
416             static const XMLCh OriginSite[];
417             static const XMLCh SiteGroup[];
418             
419             static const XMLCh Credentials[];
420             static const XMLCh Exponent[];
421             static const XMLCh KeyAuthority[];
422             static const XMLCh KeyUse[];
423             static const XMLCh Modulus[];
424             static const XMLCh RelyingParty[];
425             static const XMLCh RetrievalMethod[];
426             static const XMLCh RSAKeyValue[];
427             static const XMLCh Trust[];
428             static const XMLCh URI[];
429             static const XMLCh VerifyDepth[];
430
431             static const XMLCh Accept[];
432             static const XMLCh Alias[];
433             static const XMLCh AnySite[];
434             static const XMLCh AnyValue[];
435             static const XMLCh AttributeAcceptancePolicy[];
436             static const XMLCh AttributeRule[];
437             static const XMLCh Factory[];
438             static const XMLCh Header[];
439             static const XMLCh Namespace[];
440             static const XMLCh SiteRule[];
441             static const XMLCh Type[];
442             static const XMLCh Value[];
443
444             static const XMLCh literal[];
445             static const XMLCh regexp[];
446             static const XMLCh xpath[];
447
448             static const XMLCh technical[];
449             static const XMLCh administrative[];
450             static const XMLCh billing[];
451             static const XMLCh other[];
452
453             // XML vocabulary
454             static const XMLCh xmlns_shib[];
455         };
456     };
457
458     class SHIB_EXPORTS SAMLBindingFactory
459     {
460     public:
461         static saml::SAMLBinding* getInstance(
462             const XMLCh* subject,
463             const ISite* relyingParty,
464             const XMLCh* protocol=saml::SAMLBinding::SAML_SOAP_HTTPS);
465     };
466 }
467
468 #endif