1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 /*
21  * XSEC
22  *
23  * XKMSAuthenticationImpl := Implementation of Authentication elements
24  *
25  * $Id: XKMSAuthenticationImpl.cpp 1833340 2018-06-11 15:40:13Z scantor $
26  *
27  */
28 
29 #include <xsec/dsig/DSIGReference.hpp>
30 #include <xsec/framework/XSECDefs.hpp>
31 #include <xsec/framework/XSECEnv.hpp>
32 #include <xsec/framework/XSECError.hpp>
33 
34 #ifdef XSEC_XKMS_ENABLED
35 
36 #include "../../utils/XSECDOMUtils.hpp"
37 
38 #include "XKMSAuthenticationImpl.hpp"
39 #include "XKMSNotBoundAuthenticationImpl.hpp"
40 
41 #include <xsec/xkms/XKMSConstants.hpp>
42 
new() -> ThreadParker43 #include <xercesc/dom/DOM.hpp>
44 #include <xercesc/util/XMLUniDefs.hpp>
45 
46 XERCES_CPP_NAMESPACE_USE
47 
48 // --------------------------------------------------------------------------------
49 //           Constructor/Destructor
50 // --------------------------------------------------------------------------------
51 
52 XKMSAuthenticationImpl::XKMSAuthenticationImpl(const XSECEnv * env) :
53 mp_env(env),
54 mp_authenticationElement(NULL),
55 mp_keyBindingAuthenticationSignatureElement(NULL),
56 mp_keyBindingAuthenticationSignature(NULL),
57 mp_notBoundAuthentication(NULL)
58 {
59 }
60 
61 XKMSAuthenticationImpl::XKMSAuthenticationImpl(const XSECEnv * env, DOMElement * node) :
timed_out(&self) -> bool62 mp_env(env),
63 mp_authenticationElement(node),
64 mp_keyBindingAuthenticationSignatureElement(NULL),
65 mp_keyBindingAuthenticationSignature(NULL),
66 mp_notBoundAuthentication(NULL)
67 {
68 }
69 
70 XKMSAuthenticationImpl::~XKMSAuthenticationImpl() {
71 
72 	if (mp_notBoundAuthentication != NULL)
73 		delete mp_notBoundAuthentication;
74 }
park(&self)75 
76 // --------------------------------------------------------------------------------
77 //           Load
78 // --------------------------------------------------------------------------------
79 
80 void XKMSAuthenticationImpl::load(const XMLCh * id) {
81 
82 	if (mp_authenticationElement == NULL) {
83 		throw XSECException(XSECException::ExpectedXKMSChildNotFound,
84 			"XKMSAuthenticationImpl::load - called on empty DOM");
85 	}
86 
87 	// Store for later use
88 	mp_keyBindingId = id;
89 
90 	DOMElement * tmpElt = findFirstElementChild(mp_authenticationElement);
91 
92 	if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt),
93 									XKMSConstants::s_tagKeyBindingAuthentication)) {
94 
95 		// Find the signature
96 		mp_keyBindingAuthenticationSignatureElement =
97 			(DOMElement *) findFirstElementChild(tmpElt);
98 
99 		while (mp_keyBindingAuthenticationSignatureElement != NULL &&
100 			!strEquals(getDSIGLocalName(mp_keyBindingAuthenticationSignatureElement),
101 						XKMSConstants::s_tagSignature)) {
102 
103 			mp_keyBindingAuthenticationSignatureElement=
104 				findNextElementChild(mp_keyBindingAuthenticationSignatureElement);
105 
106 		}
107 
108 		// The provider will take care of cleaning this up later.
109 
110 		if (mp_keyBindingAuthenticationSignatureElement != NULL) {
111 
112 			mp_keyBindingAuthenticationSignature = m_prov.newSignatureFromDOM(
113 													  mp_keyBindingAuthenticationSignatureElement->getOwnerDocument(),
114 													  mp_keyBindingAuthenticationSignatureElement);
115 			mp_keyBindingAuthenticationSignature->load();
116 
117 			// Check the signature is across the correct input
118 
119 			DSIGReferenceList * rl =
120 				mp_keyBindingAuthenticationSignature->getReferenceList();
121 
122 			if (rl->getSize() != 1) {
123 				throw XSECException(XSECException::XKMSError,
124 					"XKMSAuthenticationImpl::load - KeyBindingAuthentication Signature with incorrect number of references found (should be 1)");
125 			}
126 
127 			safeBuffer sb;
128 			sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
129 			sb.sbXMLChAppendCh(chPound);
130 			sb.sbXMLChCat(mp_keyBindingId);
131 
132 			if (!strEquals(rl->item(0)->getURI(), sb.rawXMLChBuffer())) {
133 				throw XSECException(XSECException::XKMSError,
134 					"XKMSAuthenticationImpl::load - KeyBindingAuthentication Signature refers to incorrect Id (should be for KeyBinding)");
135 			}
136 
137 			// We don't actually check the signature as we have no key material to do so!
138 		}
139 
140 		tmpElt = findNextElementChild(tmpElt);
141 
142 	}
143 
144 	if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt),
145 									XKMSConstants::s_tagNotBoundAuthentication)) {
146 
147 		XSECnew(mp_notBoundAuthentication, XKMSNotBoundAuthenticationImpl(mp_env, tmpElt));
148 		mp_notBoundAuthentication->load();
149 
150 	}
151 
152 }
153 
drop(&mut self)154 // --------------------------------------------------------------------------------
155 //           Create
156 // --------------------------------------------------------------------------------
157 
158 DOMElement * XKMSAuthenticationImpl::createBlankAuthentication(const XMLCh * id) {
159 
160 	// Get some setup values
161 	safeBuffer str;
162 	DOMDocument *doc = mp_env->getParentDocument();
163 	const XMLCh * prefix = mp_env->getXKMSNSPrefix();
164 
165 	makeQName(str, prefix, XKMSConstants::s_tagAuthentication);
166 
167 	mp_authenticationElement = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
168 												str.rawXMLChBuffer());
169 
170 	mp_env->doPrettyPrint(mp_authenticationElement);
171 
172 	// This isn't used immediately - it is simply held for when we create a signature
173 	mp_keyBindingId = id;
174 
175 	return mp_authenticationElement;
176 
177 }
178 
179 
180 // --------------------------------------------------------------------------------
181 //           Interfacet - Get
unpark(self)182 // --------------------------------------------------------------------------------
183 
184 DSIGSignature * XKMSAuthenticationImpl::getKeyBindingAuthenticationSignature(void) const {
185 
186 	return mp_keyBindingAuthenticationSignature;
187 
188 }
189 
190 XKMSNotBoundAuthentication * XKMSAuthenticationImpl::getNotBoundAuthentication(void) const {
191 
192 	return mp_notBoundAuthentication;
193 
194 }
195 
196 // --------------------------------------------------------------------------------
197 //           Interface - Set
timespec_now() -> libc::timespec198 // --------------------------------------------------------------------------------
199 
200 DSIGSignature * XKMSAuthenticationImpl::addKeyBindingAuthenticationSignature(
201                 const XMLCh* c14nAlgorithm,
202 		const XMLCh* signatureAlgorithm,
203 		const XMLCh* hashAlgorithm) {
204 
205 	if (mp_keyBindingId == NULL) {
206 		throw XSECException(XSECException::XKMSError,
207 			"XKMSAuthenticationImpl::addKeyBindingAuthenticationSignature - called prior to key infos being added");
208 	}
209 
210 	DSIGSignature * ret = m_prov.newSignature();
211 	DOMElement * elt = ret->createBlankSignature(mp_env->getParentDocument(), c14nAlgorithm, signatureAlgorithm);
212 
213 	/* Create the enveloping reference */
214 	safeBuffer sb;
215 	sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
216 	sb.sbXMLChAppendCh(chPound);
217 	sb.sbXMLChCat(mp_keyBindingId);
218 
219 	DSIGReference *ref = ret->createReference(sb.rawXMLChBuffer(), hashAlgorithm);
220 	ref->appendCanonicalizationTransform(DSIGConstants::s_unicodeStrURIEXC_C14N_COM);
221 
222 	/* Embed the signature in the document inside a KeyBindingAuthentication element */
223 	safeBuffer str;
224 	DOMDocument *doc = mp_env->getParentDocument();
225 	const XMLCh * prefix = mp_env->getXKMSNSPrefix();
226 
227 	makeQName(str, prefix, XKMSConstants::s_tagKeyBindingAuthentication);
228 
229 	DOMElement * t = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
230 												str.rawXMLChBuffer());
231 
232 	mp_env->doPrettyPrint(t);
233 	t->appendChild(elt);
234 	mp_env->doPrettyPrint(t);
235 
236 	mp_authenticationElement->appendChild(t);
237 	mp_env->doPrettyPrint(mp_authenticationElement);
238 
239 	return ret;
240 }
241 
242 void XKMSAuthenticationImpl::setNotBoundAuthentication(
243 		const XMLCh * uri,
244 		const XMLCh * value) {
245 
246 	XSECnew(mp_notBoundAuthentication, XKMSNotBoundAuthenticationImpl(mp_env));
247 	mp_authenticationElement->appendChild(mp_notBoundAuthentication->createBlankNotBoundAuthentication(uri, value));
248 	mp_env->doPrettyPrint(mp_authenticationElement);
249 
thread_yield()250 }
251 
252 #endif /* XSEC_XKMS_ENABLED */
253