79553e624abcd87b79b542bfdcf236a512f4fa06
[shibboleth/cpp-xmltooling.git] / xmltooling / encryption / impl / EncryptedKeyResolver.cpp
1 /*
2  *  Copyright 2001-2010 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  * EncryptedKeyResolver.cpp
19  * 
20  * Resolves encrypted keys based on EncryptedData information or other external factors.
21  */
22
23 #include "internal.h"
24 #include "encryption/EncryptedKeyResolver.h"
25 #include "signature/KeyInfo.h"
26
27 #include <xercesc/util/XMLUniDefs.hpp>
28
29 using namespace xmlencryption;
30 using namespace xmlsignature;
31 using namespace xmltooling;
32 using namespace xercesc;
33 using namespace std;
34
35 EncryptedKeyResolver::EncryptedKeyResolver()
36 {
37 }
38
39 EncryptedKeyResolver::~EncryptedKeyResolver()
40 {
41 }
42
43 const EncryptedKey* EncryptedKeyResolver::resolveKey(const EncryptedData& encryptedData, const XMLCh* recipient) const
44 {
45     if (!encryptedData.getKeyInfo())
46         return nullptr;
47
48     const vector<XMLObject*>& others = const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getUnknownXMLObjects();
49     for (vector<XMLObject*>::const_iterator i = others.begin(); i != others.end(); i++) {
50         EncryptedKey* encKey = dynamic_cast<EncryptedKey*>(*i);
51         if (encKey) {
52             if (!recipient || !encKey->getRecipient() || XMLString::equals(recipient,encKey->getRecipient()))
53                 return encKey;
54         }
55     }
56
57     static const XMLCh rmtype[] = { // http://www.w3.org/2001/04/xmlenc#EncryptedKey
58         chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
59         chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
60         chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash, chDigit_0, chDigit_4, chForwardSlash,
61         chLatin_x, chLatin_m, chLatin_l, chLatin_e, chLatin_n, chLatin_c, chPound,
62         chLatin_E, chLatin_n, chLatin_c, chLatin_r, chLatin_y, chLatin_p, chLatin_t, chLatin_e, chLatin_d, chLatin_K, chLatin_e, chLatin_y, chNull
63     };
64
65     const XMLObject* treeRoot = nullptr;
66     const vector<RetrievalMethod*>& methods = const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getRetrievalMethods();
67     for (vector<RetrievalMethod*>::const_iterator m = methods.begin(); m != methods.end(); ++m) {
68         if (XMLString::equals((*m)->getType(), rmtype)) {
69             const XMLCh* ref = (*m)->getURI();
70             if (ref && *ref == chPound) {
71                 if (!treeRoot) {
72                     treeRoot = &encryptedData;
73                     while (treeRoot->getParent())
74                         treeRoot = treeRoot->getParent();
75                 }
76                 const EncryptedKey* encKey = dynamic_cast<const EncryptedKey*>(XMLHelper::getXMLObjectById(*treeRoot, ref+1));
77                 if (encKey)
78                     return encKey;
79             }
80         }
81     }
82
83     return nullptr;
84 }