2 * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
19 * @author Krishna Raghottam Devale (k.devale@samsung.com)
\r
20 * @brief PropertyApi class
\r
24 /*-----------------------------------------------------------------------------
\r
26 *-----------------------------------------------------------------------------*/
\r
27 #include <PropertyAccess/Property.h>
\r
28 #include <PropertyAccess/PropertyApi.h>
\r
29 #include <PropertyAccess/ClientProperty.h>
\r
30 #include <PropertyAccess/TEEProperty.h>
\r
31 #include <PropertyAccess/TAProperty.h>
\r
32 #include <PropertyAccess/PropertyUtility.h>
\r
38 using namespace std;
\r
40 // PRIVATE TO THIS API FILE
\r
41 static Property* clientProperty;
\r
42 static Property* taProperty;
\r
43 static Property* teeProperty;
\r
44 static uint32_t clientLoginGlobal = 0;
\r
45 static string thisTAUUIDGlobal = "";
\r
46 bool _allowPropertyAccess = false;
\r
49 * Static local function to identify the right object of Property
\r
50 * If propsetOrEnumerator is a constant propset then existing objects of
\r
51 * Property on given propset is returned. If propsetOrEnumerator is a handle to
\r
52 * an enumerator then PropertyEnumHandle object is returned.
\r
53 * @param propsetOrEnumerator[in] A handle of type TEE_PropSetHandle
\r
54 * @return NULL if handle is invalid else returns valid handle
\r
56 static Property* _GetTargetProperty(TEE_PropSetHandle propsetOrEnumerator);
\r
57 static uintptr_t _GetTargetPropsetType(TEE_PropSetHandle propsetOrEnumerator);
\r
62 } PropertyEnumHandle;
\r
64 std::set<PropertyEnumHandle*> propertyEnumHandleSet;
\r
66 /*-----------------------------------------------------------------------------
\r
68 *-----------------------------------------------------------------------------*/
\r
70 * Initialization routine of PropertyAccess Module. This function should be
\r
71 * called when TA stub starts with UUID of this TA.
\r
72 * @param uuid[in] UUID of our TA
\r
73 * @param taDir[in] Directory in which TA resides
\r
74 * @param clientLogin[in] login method to this TA from client.
\r
75 * Refer Table 4-13: Client Identities
\r
76 * @return TEE_ERROR_OUT_OF_MEMORY on failure to initialize else TEE_SUCCESS
\r
78 TEE_Result InitPropertyModule(const std::string& uuid,
\r
79 const std::string& taDir, uint32_t clientLogin) {
\r
81 pv.type = "identity";
\r
82 pv.value = "" + clientLogin;
\r
84 clientLoginGlobal = clientLogin;
\r
85 thisTAUUIDGlobal = uuid;
\r
88 clientProperty = new ClientProperty(pv);
\r
89 clientProperty->start();
\r
90 teeProperty = new TEEProperty();
\r
91 teeProperty->start();
\r
92 taProperty = new TAProperty(taDir + uuid + ".manifest");
\r
93 taProperty->start();
\r
94 } catch (std::bad_alloc &ba) {
\r
95 return TEE_ERROR_OUT_OF_MEMORY;
\r
101 * Deallocate Property Access objects
\r
103 void DeInitPropertyModule() {
\r
104 delete clientProperty;
\r
106 delete teeProperty;
\r
109 string getQueryProp(TEE_PropSetHandle propsetOrEnumerator, string name) {
\r
111 uintptr_t propSet = _GetTargetPropsetType(propsetOrEnumerator);
\r
112 if(propSet == TEE_PROPSET_CURRENT_TA &&
\r
113 (pos = name.rfind(".")) != string::npos) {
\r
114 return name.substr(pos + 1);
\r
119 //TODO: TEE_ERROR_ITEM_NOT_FOUND also to be returned when the string
\r
120 //received in not UTF8 encoded format
\r
121 //Assuming valueBufferLen is [in] param only.
\r
123 TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,
\r
124 const char* name, char* valueBuffer, size_t* valueBufferLen) {
\r
125 TEE_Result returnValue = TEE_SUCCESS;
\r
126 Property* targetProperty = NULL;
\r
128 string queryProp = "";
\r
130 if (NULL == propsetOrEnumerator){
\r
131 return TEE_ERROR_ITEM_NOT_FOUND;
\r
134 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
135 // 1. Select the enumerator object based on propset or consider given enumerator
\r
137 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
138 // 2. after selecting targetProperty fetch the property name
\r
140 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
141 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
142 if (valueBuffer && pv.value.size() < *valueBufferLen)
\r
143 strncpy(valueBuffer, pv.value.c_str(), *valueBufferLen);
\r
144 else returnValue = TEE_ERROR_SHORT_BUFFER;
\r
146 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
148 // Above is optimized version of below
\r
151 if (NULL != name && targetProperty && targetProperty->getPropertyByName(queryProp, pv))
\r
153 // SIZE FITS IN BUFFER
\r
154 if (pv.value.size() < *valueBufferLen)
\r
155 strcpy(valueBuffer, pv.value.c_str());
\r
157 returnValue = TEE_ERROR_SHORT_BUFFER;
\r
158 } else if (NULL == name && targetProperty && targetProperty->getPropertyValue(pv)) {
\r
159 if (pv.value.size() < *valueBufferLen)
\r
160 strcpy(valueBuffer, pv.value.c_str());
\r
162 returnValue = TEE_ERROR_SHORT_BUFFER;
\r
164 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
166 return returnValue;
\r
169 TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,
\r
170 const char* name, bool* value) {
\r
171 TEE_Result returnValue = TEE_SUCCESS;
\r
172 Property* targetProperty = NULL;
\r
174 string queryProp = "";
\r
175 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
176 // 1. Select the enumerator object based on propset or consider given enumerator
\r
178 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
179 // 2. after selecting targetProperty fetch the property by name or as in
\r
180 // pointed by enumerator marker
\r
182 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
183 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
184 returnValue = PropertyUtility::convertToBool(pv, *value);
\r
186 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
187 // Above is optimized version of below
\r
189 if (NULL != name && targetProperty && targetProperty->getPropertyByName(queryProp, pv))
\r
191 returnValue = PropertyUtility::convertToBool(pv, *value);
\r
192 } else if (NULL == name && targetProperty && targetProperty->getPropertyValue(pv)) {
\r
193 returnValue = PropertyUtility::convertToBool(pv, *value);
\r
195 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
197 return returnValue;
\r
200 TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,
\r
201 const char* name, uint32_t* value) {
\r
202 TEE_Result returnValue = TEE_SUCCESS;
\r
203 Property* targetProperty = NULL;
\r
205 string queryProp = "";
\r
206 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
207 // 1. Select the enumerator object based on propset or consider given enumerator
\r
209 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
210 // 2. after selecting targetProperty fetch the property by name or as in
\r
211 // pointed by enumerator marker
\r
213 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
214 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
215 returnValue = PropertyUtility::convertToU32(pv, *value);
\r
217 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
218 return returnValue;
\r
221 TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
\r
222 const char* name, void* valueBuffer, size_t* valueBufferLen) {
\r
223 TEE_Result returnValue = TEE_SUCCESS;
\r
224 Property* targetProperty = NULL;
\r
226 string queryProp = "";
\r
227 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
228 // Select the enumerator object based on propset or consider given enumerator
\r
230 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
231 // After selecting targetProperty fetch the property name
\r
233 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
234 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
235 string binaryBlockOut;
\r
236 returnValue = PropertyUtility::convertToBinaryBlock(pv, binaryBlockOut);
\r
237 bool conversionStatus = (returnValue == TEE_SUCCESS) ? true : false;
\r
238 if (valueBuffer && conversionStatus
\r
239 && binaryBlockOut.size() < *valueBufferLen) {
\r
240 strncpy((char*)valueBuffer, binaryBlockOut.c_str(), *valueBufferLen);
\r
242 else returnValue = TEE_ERROR_SHORT_BUFFER;
\r
244 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
245 return returnValue;
\r
248 // TODO: In spec: value: A pointer filled with the UUID. MUST NOT be NULL.
\r
249 // What does it mean? Must not be NULL
\r
250 TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,
\r
251 const char* name, TEE_UUID* value) {
\r
252 TEE_Result returnValue = TEE_SUCCESS;
\r
253 Property* targetProperty = NULL;
\r
255 string queryProp = "";
\r
256 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
257 // 1. Select the enumerator object based on propset or consider given enumerator
\r
259 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
260 // 2. after selecting targetProperty fetch the property by name or as in
\r
261 // pointed by enumerator marker
\r
263 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
264 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
265 returnValue = PropertyUtility::convertToUUID(pv, *value);
\r
267 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
268 return returnValue;
\r
271 // TODO: In spec: value: A pointer filled with the UUID. MUST NOT be NULL.
\r
272 // What does it mean? Must not be NULL
\r
273 TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,
\r
274 const char* name, TEE_Identity* value) {
\r
275 TEE_Result returnValue = TEE_SUCCESS;
\r
276 Property* targetProperty = NULL;
\r
278 string queryProp = "";
\r
279 if (NULL != name) queryProp = getQueryProp(propsetOrEnumerator, name);
\r
280 // 1. Select the enumerator object based on propset or consider given enumerator
\r
282 targetProperty = _GetTargetProperty(propsetOrEnumerator);
\r
283 // 2. after selecting targetProperty fetch the property by name or as in
\r
284 // pointed by enumerator marker
\r
286 && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))
\r
287 || (NULL == name && targetProperty->getPropertyValue(pv)))) {
\r
288 returnValue = PropertyUtility::convertToIdentity(pv, *value);
\r
290 else returnValue = TEE_ERROR_ITEM_NOT_FOUND;
\r
291 return returnValue;
\r
294 TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle* enumerator) {
\r
296 PropertyEnumHandle *newEnumHandle = new PropertyEnumHandle;
\r
297 newEnumHandle->property = NULL;
\r
298 *enumerator = (TEE_PropSetHandle)newEnumHandle;
\r
299 propertyEnumHandleSet.insert(newEnumHandle);
\r
300 } catch (std::bad_alloc &ba) {
\r
301 return TEE_ERROR_OUT_OF_MEMORY;
\r
303 return TEE_SUCCESS;
\r
306 void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) {
\r
307 PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;
\r
308 if (enumeratorHandle) {
\r
309 set<PropertyEnumHandle*>::iterator it = propertyEnumHandleSet.find((PropertyEnumHandle*)enumerator);
\r
310 if(it != propertyEnumHandleSet.end())
\r
312 propertyEnumHandleSet.erase(it);
\r
313 delete enumeratorHandle->property;
\r
314 delete enumeratorHandle;
\r
321 //TODO: propSet value sent from user has to typecased to TEE_PropSetHandle
\r
322 // this shouldnt happen, make it straight
\r
323 void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,
\r
324 TEE_PropSetHandle propSet) {
\r
325 PropertyEnumHandle *newEnumHandle = (PropertyEnumHandle*)enumerator;
\r
326 switch ((uintptr_t)propSet) {
\r
327 case TEE_PROPSET_CURRENT_TA: {
\r
328 newEnumHandle->property = new TAProperty(
\r
329 string(TEE_EXTRACT_ROOT) + thisTAUUIDGlobal + "-ext/"
\r
330 + thisTAUUIDGlobal + ".manifest");
\r
333 case TEE_PROPSET_CURRENT_CLIENT: {
\r
335 pv.type = "identity";
\r
336 pv.value = "" + clientLoginGlobal;
\r
337 if(!_allowPropertyAccess)
\r
341 newEnumHandle->property = new ClientProperty(pv);
\r
344 case TEE_PROPSET_TEE_IMPLEMENTATION: {
\r
345 newEnumHandle->property = new TEEProperty();
\r
354 if (newEnumHandle && newEnumHandle->property) {
\r
355 newEnumHandle->property->setPropSet((uintptr_t)propSet);
\r
356 newEnumHandle->property->start();
360 void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) {
\r
361 Property* targetProperty = _GetTargetProperty(enumerator);
362 if (targetProperty != NULL
363 && targetProperty != teeProperty
364 && targetProperty != clientProperty
365 && targetProperty != taProperty) {
366 PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;
367 delete enumeratorHandle->property;
368 enumeratorHandle->property = NULL;
373 * Considers nameBufferLen as [in] param as spec. is ambiguous
\r
375 TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, void* nameBuffer,
\r
376 size_t* nameBufferLen) {
\r
377 Property* targetProperty = NULL;
\r
378 // 1. Select the enumerator object based on propset or consider given enumerator
\r
380 targetProperty = _GetTargetProperty(enumerator);
\r
381 PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;
\r
382 // Check if enumerator and property are valid
\r
383 //if (enumeratorHandle && enumeratorHandle->property) {
\r
384 if (enumeratorHandle && targetProperty) {
\r
386 // If item exists and and not reached end of enumerator, get the name
\r
387 if (enumeratorHandle->property->getPropertyName(propName)) {
\r
388 if (*nameBufferLen < propName.size() + 1) return TEE_ERROR_SHORT_BUFFER;
\r
389 strncpy((char*)nameBuffer, propName.c_str(), *nameBufferLen);
\r
391 // item not found or enumerator end has reached
\r
392 else return TEE_ERROR_ITEM_NOT_FOUND;
\r
394 else return TEE_ERROR_ITEM_NOT_FOUND;
\r
395 return TEE_SUCCESS;
\r
398 TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) {
\r
399 PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;
\r
400 // Check if enumerator and property are valid and enumerator has not reached end of enum
\r
401 if (enumeratorHandle && enumeratorHandle->property
\r
402 && enumeratorHandle->property->getNextProperty()) {
\r
403 return TEE_SUCCESS;
\r
405 else return TEE_ERROR_ITEM_NOT_FOUND;
\r
408 uintptr_t _GetTargetPropsetType(TEE_PropSetHandle propsetOrEnumerator) {
\r
409 switch ((uintptr_t)propsetOrEnumerator) {
\r
410 case TEE_PROPSET_TEE_IMPLEMENTATION:
\r
411 case TEE_PROPSET_CURRENT_CLIENT:
\r
412 case TEE_PROPSET_CURRENT_TA:
\r
413 return (uintptr_t)propsetOrEnumerator;
\r
415 set<PropertyEnumHandle*>::iterator it =
\r
416 propertyEnumHandleSet.find((PropertyEnumHandle*)propsetOrEnumerator);
\r
417 if(it != propertyEnumHandleSet.end()) {
\r
418 Property *targetProperty = NULL;
\r
419 PropertyEnumHandle *enumHandle =
\r
420 (PropertyEnumHandle*)propsetOrEnumerator;
\r
421 if (enumHandle && enumHandle->property) {
\r
422 targetProperty = enumHandle->property;
\r
423 return targetProperty->m_propset;
\r
429 Property* _GetTargetProperty(TEE_PropSetHandle propsetOrEnumerator) {
\r
430 Property *targetProperty = NULL;
\r
431 switch ((uintptr_t)propsetOrEnumerator) {
\r
432 case TEE_PROPSET_TEE_IMPLEMENTATION: {
\r
433 targetProperty = teeProperty;
\r
436 case TEE_PROPSET_CURRENT_CLIENT: {
\r
437 if(!_allowPropertyAccess)
\r
441 targetProperty = clientProperty;
\r
444 case TEE_PROPSET_CURRENT_TA: {
\r
445 targetProperty = taProperty;
\r
449 if(targetProperty == NULL) {
\r
450 set<PropertyEnumHandle*>::iterator it =
\r
451 propertyEnumHandleSet.find((PropertyEnumHandle*)propsetOrEnumerator);
\r
452 if(it != propertyEnumHandleSet.end()) {
\r
453 PropertyEnumHandle *enumHandle =
\r
454 (PropertyEnumHandle*)propsetOrEnumerator;
\r
455 if (enumHandle && enumHandle->property)
\r
456 targetProperty = enumHandle->property;
\r
459 return targetProperty;
\r