Multi-line svn commit, see body.
[shibboleth/cpp-xmltooling.git] / xmltooling / security / impl / StaticPKIXTrustEngine.cpp
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  * PKIXTrustEngine.cpp
19  * 
20  * Shibboleth-specific PKIX-validation TrustEngine
21  */
22
23 #include "internal.h"
24
25 #include "logging.h"
26 #include "XMLToolingConfig.h"
27 #include "security/AbstractPKIXTrustEngine.h"
28 #include "security/CredentialResolver.h"
29 #include "security/X509Credential.h"
30 #include "util/XMLHelper.h"
31
32 #include <xercesc/util/XMLUniDefs.hpp>
33
34 using namespace xmlsignature;
35 using namespace xmltooling;
36 using namespace xercesc;
37 using namespace std;
38
39 namespace xmltooling {
40
41     static const XMLCh _CredentialResolver[] =  UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
42     static const XMLCh type[] =                 UNICODE_LITERAL_4(t,y,p,e);
43     static const XMLCh certificate[] =          UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e);
44     static const XMLCh Certificate[] =          UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);
45     static const XMLCh Path[] =                 UNICODE_LITERAL_4(P,a,t,h);
46     static const XMLCh verifyDepth[] =          UNICODE_LITERAL_11(v,e,r,i,f,y,D,e,p,t,h);
47
48     class XMLTOOL_DLLLOCAL StaticPKIXTrustEngine : public AbstractPKIXTrustEngine
49     {
50     public:
51         StaticPKIXTrustEngine(const DOMElement* e=NULL);
52
53         virtual ~StaticPKIXTrustEngine() {
54             if (m_credResolver) {
55                 m_credResolver->unlock();
56                 delete m_credResolver;
57             }
58         }
59         
60         AbstractPKIXTrustEngine::PKIXValidationInfoIterator* getPKIXValidationInfoIterator(
61             const CredentialResolver& pkixSource, CredentialCriteria* criteria=NULL
62             ) const;
63
64         const KeyInfoResolver* getKeyInfoResolver() const {
65             return m_keyInfoResolver ? m_keyInfoResolver : XMLToolingConfig::getConfig().getKeyInfoResolver();
66         }
67
68     private:
69         CredentialResolver* m_credResolver;
70         int m_depth;
71         vector<XSECCryptoX509*> m_certs;
72         vector<XSECCryptoX509CRL*> m_crls;
73         friend class XMLTOOL_DLLLOCAL StaticPKIXIterator;
74     };
75     
76     TrustEngine* XMLTOOL_DLLLOCAL StaticPKIXTrustEngineFactory(const DOMElement* const & e)
77     {
78         return new StaticPKIXTrustEngine(e);
79     }
80
81     class XMLTOOL_DLLLOCAL StaticPKIXIterator : public AbstractPKIXTrustEngine::PKIXValidationInfoIterator
82     {
83     public:
84         StaticPKIXIterator(const StaticPKIXTrustEngine& engine) : m_engine(engine), m_done(false) {
85         }
86
87         virtual ~StaticPKIXIterator() {
88         }
89
90         bool next() {
91             if (m_done)
92                 return false;
93             m_done = true;
94             return true;
95         }
96
97         int getVerificationDepth() const {
98             return m_engine.m_depth;
99         }
100         
101         const vector<XSECCryptoX509*>& getTrustAnchors() const {
102             return m_engine.m_certs;
103         }
104
105         const vector<XSECCryptoX509CRL*>& getCRLs() const {
106             return m_engine.m_crls;
107         }
108     
109     private:
110         const StaticPKIXTrustEngine& m_engine;
111         bool m_done;
112     };
113 };
114
115 StaticPKIXTrustEngine::StaticPKIXTrustEngine(const DOMElement* e) : AbstractPKIXTrustEngine(e)
116 {
117     const XMLCh* depth = e ? e->getAttributeNS(NULL, verifyDepth) : NULL;
118     if (depth && *depth)
119         m_depth = XMLString::parseInt(depth);
120     else
121         m_depth = 1;
122
123     if (e && e->hasAttributeNS(NULL,certificate)) {
124         // Simple File resolver config rooted here.
125         m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(FILESYSTEM_CREDENTIAL_RESOLVER,e);
126     }
127     else {
128         e = e ? XMLHelper::getFirstChildElement(e, _CredentialResolver) : NULL;
129         auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL);
130         if (t.get()) {
131             m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(t.get(),e);
132         }
133         else
134             throw XMLSecurityException("Missing <CredentialResolver> element, or no type attribute found");
135     }
136
137     m_credResolver->lock();
138
139     // Merge together all X509Credentials we can resolve.
140     try {
141         vector<const Credential*> creds;
142         m_credResolver->resolve(creds);
143         for (vector<const Credential*>::const_iterator i = creds.begin(); i != creds.end(); ++i) {
144             const X509Credential* xcred = dynamic_cast<const X509Credential*>(*i);
145             if (xcred) {
146                 m_certs.insert(m_certs.end(), xcred->getEntityCertificateChain().begin(), xcred->getEntityCertificateChain().end());
147                 m_crls.insert(m_crls.end(), xcred->getCRLs().begin(), xcred->getCRLs().end());
148             }
149         }
150     }
151     catch (exception& ex) {
152         logging::Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine.StaticPKIX").error(ex.what());
153     }
154 }
155
156 AbstractPKIXTrustEngine::PKIXValidationInfoIterator* StaticPKIXTrustEngine::getPKIXValidationInfoIterator(
157     const CredentialResolver& pkixSource, CredentialCriteria* criteria
158     ) const
159 {
160     return new StaticPKIXIterator(*this);
161 }