Major revamp of credential and trust handling code, PKIX engine still needs work.
[shibboleth/cpp-xmltooling.git] / xmltooling / security / impl / ChainingTrustEngine.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  * ChainingTrustEngine.cpp
19  * 
20  * TrustEngine that uses multiple engines in sequence.
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "security/ChainingTrustEngine.h"
26 #include "util/XMLHelper.h"
27
28 #include <log4cpp/Category.hh>
29 #include <xercesc/util/XMLUniDefs.hpp>
30
31 using namespace xmlsignature;
32 using namespace xmltooling;
33 using namespace log4cpp;
34 using namespace std;
35
36 namespace xmltooling {
37     TrustEngine* XMLTOOL_DLLLOCAL ChainingTrustEngineFactory(const DOMElement* const & e)
38     {
39         return new ChainingTrustEngine(e);
40     }
41 };
42
43 static const XMLCh _TrustEngine[] =                 UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
44 static const XMLCh type[] =                         UNICODE_LITERAL_4(t,y,p,e);
45
46 ChainingTrustEngine::ChainingTrustEngine(const DOMElement* e) : OpenSSLTrustEngine(e) {
47     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
48     try {
49         e = e ? XMLHelper::getFirstChildElement(e, _TrustEngine) : NULL;
50         while (e) {
51             auto_ptr_char temp(e->getAttributeNS(NULL,type));
52             if (temp.get() && *temp.get()) {
53                 log.info("building TrustEngine of type %s", temp.get());
54                 m_engines.push_back(XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(temp.get(), e));
55             }
56             e = XMLHelper::getNextSiblingElement(e, _TrustEngine);
57         }
58     }
59     catch (exception&) {
60         for_each(m_engines.begin(), m_engines.end(), xmltooling::cleanup<TrustEngine>());
61         throw;
62     }
63 }
64
65 ChainingTrustEngine::~ChainingTrustEngine() {
66     for_each(m_engines.begin(), m_engines.end(), xmltooling::cleanup<TrustEngine>());
67 }
68
69 bool ChainingTrustEngine::validate(Signature& sig, const CredentialResolver& credResolver, CredentialCriteria* criteria) const
70 {
71     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
72         if ((*i)->validate(sig,credResolver,criteria))
73             return true;
74     }
75     return false;
76 }
77
78 bool ChainingTrustEngine::validate(
79     const XMLCh* sigAlgorithm,
80     const char* sig,
81     KeyInfo* keyInfo,
82     const char* in,
83     unsigned int in_len,
84     const CredentialResolver& credResolver,
85     CredentialCriteria* criteria
86     ) const
87 {
88     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
89         if ((*i)->validate(sigAlgorithm, sig, keyInfo, in, in_len, credResolver, criteria))
90             return true;
91     }
92     return false;
93 }
94
95 bool ChainingTrustEngine::validate(
96     XSECCryptoX509* certEE,
97     const vector<XSECCryptoX509*>& certChain,
98     const CredentialResolver& credResolver,
99     CredentialCriteria* criteria
100     ) const
101 {
102     X509TrustEngine* down;
103     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
104         if ((down = dynamic_cast<X509TrustEngine*>(*i)) &&
105                 down->validate(certEE,certChain,credResolver,criteria))
106             return true;
107     }
108     return false;
109 }
110
111 bool ChainingTrustEngine::validate(
112     X509* certEE,
113     STACK_OF(X509)* certChain,
114     const CredentialResolver& credResolver,
115     CredentialCriteria* criteria
116     ) const
117 {
118     OpenSSLTrustEngine* down;
119     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
120         if ((down = dynamic_cast<OpenSSLTrustEngine*>(*i)) && down->validate(certEE,certChain,credResolver,criteria))
121             return true;
122     }
123     return false;
124 }