• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "attribute.h"
17 
18 #include "securec.h"
19 
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22 
23 #ifdef IAM_TEST_ENABLE
24 #define IAM_STATIC
25 #else
26 #define IAM_STATIC static
27 #endif
28 
29 #define SUCCESS RESULT_SUCCESS
30 #define GENERAL_ERROR RESULT_GENERAL_ERROR
31 #define INVALID_PARAMETERS RESULT_BAD_PARAM
32 
33 AttributeKey g_attributeKeyArray[] = {
34     AUTH_RESULT_CODE,
35     AUTH_SIGNATURE,
36     AUTH_IDENTIFY_MODE,
37     AUTH_TEMPLATE_ID,
38     AUTH_TEMPLATE_ID_LIST,
39     AUTH_REMAIN_COUNT,
40     AUTH_REMAIN_TIME,
41     AUTH_CALLER_NAME,
42     AUTH_SCHEDULE_ID,
43     AUTH_SCHEDULE_VERSION,
44     AUTH_LOCK_OUT_TEMPLATE,
45     AUTH_UNLOCK_TEMPLATE,
46     AUTH_DATA,
47     AUTH_SUB_TYPE,
48     AUTH_SCHEDULE_MODE,
49     AUTH_PROPERTY_MODE,
50     AUTH_TYPE,
51     AUTH_CREDENTIAL_ID,
52     AUTH_CONTROLLER,
53     AUTH_CALLER_UID,
54     AUTH_RESULT,
55     AUTH_CAPABILITY_LEVEL,
56     AUTH_ALGORITHM_INFO,
57     AUTH_TIME_STAMP,
58     AUTH_ROOT_SECRET,
59     AUTH_ROOT,
60 };
61 
62 #define ARRAY_LENGTH(array) (uint32_t)(sizeof(array) / sizeof((array)[0]))
63 #define ATTRIBUTE_LEN (ARRAY_LENGTH(g_attributeKeyArray))
64 
65 typedef struct {
66     Uint8Array *values[ATTRIBUTE_LEN];
67 } AttributeImpl;
68 
Ntohl32(uint32_t in)69 IAM_STATIC uint32_t Ntohl32(uint32_t in)
70 {
71     return in;
72 }
73 
Htonl32(uint32_t in)74 IAM_STATIC uint32_t Htonl32(uint32_t in)
75 {
76     return in;
77 }
78 
Ntohl64(uint64_t in)79 IAM_STATIC uint64_t Ntohl64(uint64_t in)
80 {
81     return in;
82 }
83 
Htonl64(uint64_t in)84 IAM_STATIC uint64_t Htonl64(uint64_t in)
85 {
86     return in;
87 }
88 
Ntohl64Array(Uint64Array * array)89 IAM_STATIC void Ntohl64Array(Uint64Array *array)
90 {
91     for (uint32_t i = 0; i < array->len; i++) {
92         array->data[i] = Ntohl64(array->data[i]);
93     }
94 }
95 
Htonl64Array(Uint64Array * array)96 IAM_STATIC void Htonl64Array(Uint64Array *array)
97 {
98     for (uint32_t i = 0; i < array->len; i++) {
99         array->data[i] = Htonl64(array->data[i]);
100     }
101 }
102 
GetAttributeIndex(AttributeKey key,uint32_t * index)103 IAM_STATIC ResultCode GetAttributeIndex(AttributeKey key, uint32_t *index)
104 {
105     for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
106         if (g_attributeKeyArray[i] == key) {
107             *index = i;
108             return SUCCESS;
109         }
110     }
111 
112     return GENERAL_ERROR;
113 }
114 
ReadDataFromMsg(const Uint8Array msg,uint32_t * readIndex,Uint8Array * retData)115 IAM_STATIC ResultCode ReadDataFromMsg(const Uint8Array msg, uint32_t *readIndex, Uint8Array *retData)
116 {
117     if (msg.len <= *readIndex) {
118         LOG_ERROR("msg length is not enough");
119         return GENERAL_ERROR;
120     }
121 
122     if (msg.len - *readIndex < retData->len) {
123         LOG_ERROR("remain data length is not enough");
124         return GENERAL_ERROR;
125     }
126 
127     if (memcpy_s(retData->data, retData->len, msg.data + *readIndex, retData->len) != EOK) {
128         LOG_ERROR("memcpy_s fail");
129         return GENERAL_ERROR;
130     }
131 
132     *readIndex += retData->len;
133     return SUCCESS;
134 }
135 
ReadUint32FromMsg(const Uint8Array msg,uint32_t * readIndex,uint32_t * retValue)136 IAM_STATIC ResultCode ReadUint32FromMsg(const Uint8Array msg, uint32_t *readIndex, uint32_t *retValue)
137 {
138     uint32_t netOrderValue;
139     Uint8Array uint8Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
140     ResultCode result = ReadDataFromMsg(msg, readIndex, &uint8Data);
141     if (result != SUCCESS) {
142         LOG_ERROR("read data fail");
143         return GENERAL_ERROR;
144     }
145 
146     *retValue = Ntohl32(netOrderValue);
147     return SUCCESS;
148 }
149 
WriteDataToMsg(Uint8Array * msg,uint32_t * writeIndex,const Uint8Array data)150 IAM_STATIC ResultCode WriteDataToMsg(Uint8Array *msg, uint32_t *writeIndex, const Uint8Array data)
151 {
152     if (msg->len <= *writeIndex) {
153         LOG_ERROR("msg length is not enough");
154         return GENERAL_ERROR;
155     }
156 
157     if (msg->len - *writeIndex < data.len) {
158         LOG_ERROR("remain data size is not enough");
159         return GENERAL_ERROR;
160     }
161 
162     if (memcpy_s(msg->data + *writeIndex, msg->len - *writeIndex, data.data, data.len) != EOK) {
163         LOG_ERROR("memcpy_s fail");
164         return GENERAL_ERROR;
165     }
166 
167     *writeIndex += data.len;
168     return SUCCESS;
169 }
170 
WriteUInt32ToMsg(Uint8Array * msg,uint32_t * writeIndex,uint32_t value)171 IAM_STATIC ResultCode WriteUInt32ToMsg(Uint8Array *msg, uint32_t *writeIndex, uint32_t value)
172 {
173     uint32_t netOrderValue = Htonl32(value);
174     ResultCode result =
175         WriteDataToMsg(msg, writeIndex, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
176     if (result != SUCCESS) {
177         LOG_ERROR("write data fail");
178         return GENERAL_ERROR;
179     }
180     return SUCCESS;
181 }
182 
ParseAttributeSerializedMsgInner(Attribute * attribute,const Uint8Array msg,const Uint8Array * readBuffer)183 IAM_STATIC ResultCode ParseAttributeSerializedMsgInner(Attribute *attribute, const Uint8Array msg,
184     const Uint8Array *readBuffer)
185 {
186     uint32_t readIndex = 0;
187     while (readIndex < msg.len) {
188         uint32_t type;
189         ResultCode readTypeResult = ReadUint32FromMsg(msg, &readIndex, &type);
190         IF_TRUE_LOGE_AND_RETURN_VAL(readTypeResult != SUCCESS, GENERAL_ERROR);
191 
192         uint32_t length;
193         ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
194         IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != SUCCESS, GENERAL_ERROR);
195         IF_TRUE_LOGE_AND_RETURN_VAL(length > readBuffer->len, GENERAL_ERROR);
196 
197         Uint8Array readData = { readBuffer->data, length };
198         if (length > 0) {
199             ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &readData);
200             IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != SUCCESS, GENERAL_ERROR);
201         }
202 
203         ResultCode setAttrResult = SetAttributeUint8Array(attribute, type, readData);
204         IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
205     }
206 
207     return SUCCESS;
208 }
209 
ParseAttributeSerializedMsg(Attribute * attribute,const Uint8Array msg)210 IAM_STATIC ResultCode ParseAttributeSerializedMsg(Attribute *attribute, const Uint8Array msg)
211 {
212     Uint8Array *readBuffer = CreateUint8ArrayBySize(MAX_EXECUTOR_MSG_LEN);
213     IF_TRUE_LOGE_AND_RETURN_VAL(readBuffer == NULL, GENERAL_ERROR);
214 
215     ResultCode result = ParseAttributeSerializedMsgInner(attribute, msg, readBuffer);
216     if (result != SUCCESS) {
217         LOG_ERROR("ParseAttributeSerializedMsgInner fail");
218     }
219     DestroyUint8Array(&readBuffer);
220 
221     return result;
222 }
223 
CreateEmptyAttribute(void)224 Attribute *CreateEmptyAttribute(void)
225 {
226     AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
227     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
228     (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
229 
230     return attribute;
231 }
232 
CreateAttributeFromSerializedMsg(const Uint8Array msg)233 Attribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
234 {
235     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
236 
237     Attribute *attribute = CreateEmptyAttribute();
238     if (attribute == NULL) {
239         LOG_ERROR("CreateEmptyAttribute failed");
240         return NULL;
241     }
242 
243     ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
244     if (result != SUCCESS) {
245         LOG_ERROR("ParseAttributeSerializedMsg failed");
246         FreeAttribute((Attribute **)&attribute);
247         return NULL;
248     }
249 
250     return attribute;
251 }
252 
GetAttributeSerializedMsg(const Attribute * attributePublic,Uint8Array * retMsg)253 ResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
254 {
255     IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, INVALID_PARAMETERS);
256     IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
257     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
258 
259     const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
260     uint32_t writeIndex = 0;
261     for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
262         Uint8Array *array = attribute->values[i];
263         if (array == NULL) {
264             continue;
265         }
266 
267         ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
268         IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != SUCCESS, GENERAL_ERROR);
269 
270         ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
271         IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
272 
273         if (array->len == 0) {
274             continue;
275         }
276         ResultCode writeDataResult =
277             WriteDataToMsg(retMsg, &writeIndex, *array);
278         IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
279     }
280 
281     retMsg->len = writeIndex;
282     return SUCCESS;
283 }
284 
FreeAttribute(Attribute ** attribute)285 void FreeAttribute(Attribute **attribute)
286 {
287     IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
288     IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
289     AttributeImpl *impl = (AttributeImpl *)*attribute;
290     for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
291         DestroyUint8Array(&impl->values[i]);
292     }
293 
294     IAM_FREE_AND_SET_NULL(*attribute);
295 }
296 
GetAttributeUint32(const Attribute * attribute,AttributeKey key,uint32_t * value)297 ResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
298 {
299     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
300     IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, INVALID_PARAMETERS);
301 
302     uint32_t netOrderValue;
303     Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
304     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
305     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
306     IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), GENERAL_ERROR);
307 
308     *value = Ntohl32(netOrderValue);
309     return SUCCESS;
310 }
311 
SetAttributeUint32(Attribute * attribute,AttributeKey key,const uint32_t value)312 ResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
313 {
314     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
315 
316     uint32_t netOrderValue = Htonl32(value);
317     ResultCode result =
318         SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
319     IF_TRUE_LOGE_AND_RETURN_VAL(result != SUCCESS, GENERAL_ERROR);
320 
321     return result;
322 }
323 
GetAttributeInt32(const Attribute * attribute,AttributeKey key,int32_t * retValue)324 ResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
325 {
326     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
327     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
328 
329     return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
330 }
331 
SetAttributeInt32(Attribute * attribute,AttributeKey key,const int32_t value)332 ResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
333 {
334     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
335 
336     return SetAttributeUint32(attribute, key, (uint32_t)value);
337 }
338 
GetAttributeUint64(const Attribute * attribute,AttributeKey key,uint64_t * retValue)339 ResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
340 {
341     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
342     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
343 
344     uint64_t netOrderValue;
345     Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
346     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
347     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
348     IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), GENERAL_ERROR);
349 
350     *retValue = Ntohl64(netOrderValue);
351     return SUCCESS;
352 }
353 
SetAttributeUint64(Attribute * attribute,AttributeKey key,const uint64_t value)354 ResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
355 {
356     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
357 
358     uint64_t netOrderValue = Htonl64(value);
359     ResultCode setAttrResult =
360         SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
361     IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
362 
363     return SUCCESS;
364 }
365 
GetAttributeUint8Array(const Attribute * attributePub,AttributeKey key,Uint8Array * retData)366 ResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
367 {
368     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
369     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
370     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
371 
372     const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
373 
374     uint32_t attributeIndex;
375     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
376     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
377 
378     if (attribute->values[attributeIndex] == NULL) {
379         LOG_ERROR("data is not set");
380         return GENERAL_ERROR;
381     }
382 
383     if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
384         errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
385             attribute->values[attributeIndex]->len);
386         IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, GENERAL_ERROR);
387     } else {
388         LOG_INFO("the current data is an empty array");
389     }
390     retData->len = attribute->values[attributeIndex]->len;
391 
392     return SUCCESS;
393 }
394 
SetAttributeUint8Array(Attribute * attributePub,AttributeKey key,const Uint8Array data)395 ResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
396 {
397     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
398     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
399 
400     AttributeImpl *attribute = (AttributeImpl *)attributePub;
401 
402     uint32_t attributeIndex;
403     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
404     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
405 
406     DestroyUint8Array(&attribute->values[attributeIndex]);
407     attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
408     if (attribute->values[attributeIndex] == NULL) {
409         LOG_ERROR("CreateUint8ArrayByData fail");
410         return GENERAL_ERROR;
411     }
412 
413     return SUCCESS;
414 }
415 
GetAttributeUint64Array(const Attribute * attribute,AttributeKey key,Uint64Array * retData)416 ResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
417 {
418     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
419     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
420     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
421 
422     Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
423     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
424     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
425     if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
426         LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
427         return GENERAL_ERROR;
428     }
429     Ntohl64Array(retData);
430 
431     retData->len = uint64ArrayData.len / sizeof(uint64_t);
432     return SUCCESS;
433 }
434 
SetAttributeUint64Array(Attribute * attribute,AttributeKey key,const Uint64Array data)435 ResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
436 {
437     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
438     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
439 
440     Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
441     IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, GENERAL_ERROR);
442 
443     ResultCode result = GENERAL_ERROR;
444     do {
445         Htonl64Array(netOrderData);
446         if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
447             LOG_ERROR("netOrderData->len is invalid");
448             break;
449         }
450         result = SetAttributeUint8Array(attribute, key,
451             (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
452         if (result != SUCCESS) {
453             LOG_ERROR("SetAttributeUint8Array fail");
454             break;
455         }
456     } while (0);
457 
458     DestroyUint64Array(&netOrderData);
459     return result;
460 }
461