Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[shibboleth/cpp-xmltooling.git] / xmltooling / encryption / impl / EncryptedKeyResolver.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * EncryptedKeyResolver.cpp
23  * 
24  * Resolves encrypted keys based on EncryptedData information or other external factors.
25  */
26
27 #include "internal.h"
28 #include "encryption/EncryptedKeyResolver.h"
29 #include "signature/KeyInfo.h"
30
31 #include <xercesc/util/XMLUniDefs.hpp>
32
33 using namespace xmlencryption;
34 using namespace xmlsignature;
35 using namespace xmltooling;
36 using namespace xercesc;
37 using namespace std;
38
39 EncryptedKeyResolver::EncryptedKeyResolver()
40 {
41 }
42
43 EncryptedKeyResolver::~EncryptedKeyResolver()
44 {
45 }
46
47 const EncryptedKey* EncryptedKeyResolver::resolveKey(const EncryptedData& encryptedData, const XMLCh* recipient) const
48 {
49     if (!encryptedData.getKeyInfo())
50         return nullptr;
51
52     const vector<XMLObject*>& others = const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getUnknownXMLObjects();
53     for (vector<XMLObject*>::const_iterator i = others.begin(); i != others.end(); i++) {
54         EncryptedKey* encKey = dynamic_cast<EncryptedKey*>(*i);
55         if (encKey) {
56             if (!recipient || !encKey->getRecipient() || XMLString::equals(recipient,encKey->getRecipient()))
57                 return encKey;
58         }
59     }
60
61     static const XMLCh rmtype[] = { // http://www.w3.org/2001/04/xmlenc#EncryptedKey
62         chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
63         chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
64         chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash, chDigit_0, chDigit_4, chForwardSlash,
65         chLatin_x, chLatin_m, chLatin_l, chLatin_e, chLatin_n, chLatin_c, chPound,
66         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
67     };
68
69     const XMLObject* treeRoot = nullptr;
70     const vector<RetrievalMethod*>& methods = const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getRetrievalMethods();
71     for (vector<RetrievalMethod*>::const_iterator m = methods.begin(); m != methods.end(); ++m) {
72         if (XMLString::equals((*m)->getType(), rmtype)) {
73             const XMLCh* ref = (*m)->getURI();
74             if (ref && *ref == chPound) {
75                 if (!treeRoot) {
76                     treeRoot = &encryptedData;
77                     while (treeRoot->getParent())
78                         treeRoot = treeRoot->getParent();
79                 }
80                 const EncryptedKey* encKey = dynamic_cast<const EncryptedKey*>(XMLHelper::getXMLObjectById(*treeRoot, ref+1));
81                 if (encKey)
82                     return encKey;
83             }
84         }
85     }
86
87     return nullptr;
88 }