1 /*
2  * Copyright (C) 2023-2024 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     ATTR_RESULT_CODE,
35     ATTR_SIGNATURE,
36     ATTR_IDENTIFY_MODE,
37     ATTR_TEMPLATE_ID,
38     ATTR_TEMPLATE_ID_LIST,
39     ATTR_REMAIN_ATTEMPTS,
40     ATTR_LOCKOUT_DURATION,
41     ATTR_SCHEDULE_ID,
42     ATTR_DATA,
43     ATTR_PIN_SUB_TYPE,
44     ATTR_SCHEDULE_MODE,
45     ATTR_PROPERTY_MODE,
46     ATTR_TYPE,
47     ATTR_CREDENTIAL_ID,
48     ATTR_CONTROLLER,
49     ATTR_CALLER_UID,
50     ATTR_RESULT,
51     ATTR_CAPABILITY_LEVEL,
52     ATTR_ALGORITHM_INFO,
53     ATTR_TIME_STAMP,
54     ATTR_ROOT_SECRET,
55     ATTR_ROOT,
56     ATTR_ATTRS,
57     ATTR_EXECUTOR_INDEX,
58     ATTR_PUBLIC_KEY,
59     ATTR_EXECUTOR_MATCHER,
60     ATTR_LOCAL_UDID,
61     ATTR_PEER_UDID,
62     ATTR_LOCKOUT_DURATION,
63     ATTR_REMAIN_ATTEMPTS,
64     ATTR_USER_ID,
65     ATTR_TOKEN,
66     ATTR_EXECUTOR_ROLE,
67     ATTR_ESL,
68     ATTR_VERIFIER_UDID,
69     ATTR_COLLECTOR_UDID,
70     ATTR_CHALLENGE,
71     ATTR_EXPIRED_SYS_TIME,
72 };
73 
74 #define ARRAY_LENGTH(array) (uint32_t)(sizeof(array) / sizeof((array)[0]))
75 #define ATTRIBUTE_LEN (ARRAY_LENGTH(g_attributeKeyArray))
76 
77 typedef struct {
78     Uint8Array *values[ATTRIBUTE_LEN];
79 } AttributeImpl;
80 
Ntohl32(uint32_t in)81 IAM_STATIC uint32_t Ntohl32(uint32_t in)
82 {
83     return in;
84 }
85 
Htonl32(uint32_t in)86 IAM_STATIC uint32_t Htonl32(uint32_t in)
87 {
88     return in;
89 }
90 
Ntohl64(uint64_t in)91 IAM_STATIC uint64_t Ntohl64(uint64_t in)
92 {
93     return in;
94 }
95 
Htonl64(uint64_t in)96 IAM_STATIC uint64_t Htonl64(uint64_t in)
97 {
98     return in;
99 }
100 
Ntohl64Array(Uint64Array * array)101 IAM_STATIC void Ntohl64Array(Uint64Array *array)
102 {
103     for (uint32_t i = 0; i < array->len; i++) {
104         array->data[i] = Ntohl64(array->data[i]);
105     }
106 }
107 
Htonl64Array(Uint64Array * array)108 IAM_STATIC void Htonl64Array(Uint64Array *array)
109 {
110     for (uint32_t i = 0; i < array->len; i++) {
111         array->data[i] = Htonl64(array->data[i]);
112     }
113 }
114 
GetAttributeIndex(AttributeKey key,uint32_t * index)115 IAM_STATIC ResultCode GetAttributeIndex(AttributeKey key, uint32_t *index)
116 {
117     for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
118         if (g_attributeKeyArray[i] == key) {
119             *index = i;
120             return SUCCESS;
121         }
122     }
123 
124     return GENERAL_ERROR;
125 }
126 
ReadDataFromMsg(const Uint8Array msg,uint32_t * readIndex,Uint8Array * retData)127 IAM_STATIC ResultCode ReadDataFromMsg(const Uint8Array msg, uint32_t *readIndex, Uint8Array *retData)
128 {
129     if (msg.len <= *readIndex) {
130         LOG_ERROR("msg length is not enough");
131         return GENERAL_ERROR;
132     }
133 
134     if (msg.len - *readIndex < retData->len) {
135         LOG_ERROR("remain data length is not enough");
136         return GENERAL_ERROR;
137     }
138 
139     if (memcpy_s(retData->data, retData->len, msg.data + *readIndex, retData->len) != EOK) {
140         LOG_ERROR("memcpy_s fail");
141         return GENERAL_ERROR;
142     }
143 
144     *readIndex += retData->len;
145     return SUCCESS;
146 }
147 
ReadUint32FromMsg(const Uint8Array msg,uint32_t * readIndex,uint32_t * retValue)148 IAM_STATIC ResultCode ReadUint32FromMsg(const Uint8Array msg, uint32_t *readIndex, uint32_t *retValue)
149 {
150     uint32_t netOrderValue;
151     Uint8Array uint8Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
152     ResultCode result = ReadDataFromMsg(msg, readIndex, &uint8Data);
153     if (result != SUCCESS) {
154         LOG_ERROR("read data fail");
155         return GENERAL_ERROR;
156     }
157 
158     *retValue = Ntohl32(netOrderValue);
159     return SUCCESS;
160 }
161 
WriteDataToMsg(Uint8Array * msg,uint32_t * writeIndex,const Uint8Array data)162 IAM_STATIC ResultCode WriteDataToMsg(Uint8Array *msg, uint32_t *writeIndex, const Uint8Array data)
163 {
164     if (msg->len <= *writeIndex) {
165         LOG_ERROR("msg length is not enough");
166         return GENERAL_ERROR;
167     }
168 
169     if (msg->len - *writeIndex < data.len) {
170         LOG_ERROR("remain data size is not enough");
171         return GENERAL_ERROR;
172     }
173 
174     if (memcpy_s(msg->data + *writeIndex, msg->len - *writeIndex, data.data, data.len) != EOK) {
175         LOG_ERROR("memcpy_s fail");
176         return GENERAL_ERROR;
177     }
178 
179     *writeIndex += data.len;
180     return SUCCESS;
181 }
182 
WriteUInt32ToMsg(Uint8Array * msg,uint32_t * writeIndex,uint32_t value)183 IAM_STATIC ResultCode WriteUInt32ToMsg(Uint8Array *msg, uint32_t *writeIndex, uint32_t value)
184 {
185     uint32_t netOrderValue = Htonl32(value);
186     ResultCode result =
187         WriteDataToMsg(msg, writeIndex, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
188     if (result != SUCCESS) {
189         LOG_ERROR("write data fail");
190         return GENERAL_ERROR;
191     }
192     return SUCCESS;
193 }
194 
ParseAttributeSerializedMsgInner(Attribute * attribute,const Uint8Array msg,const Uint8Array * readBuffer)195 IAM_STATIC ResultCode ParseAttributeSerializedMsgInner(Attribute *attribute, const Uint8Array msg,
196     const Uint8Array *readBuffer)
197 {
198     uint32_t readIndex = 0;
199     while (readIndex < msg.len) {
200         uint32_t type;
201         ResultCode readTypeResult = ReadUint32FromMsg(msg, &readIndex, &type);
202         IF_TRUE_LOGE_AND_RETURN_VAL(readTypeResult != SUCCESS, GENERAL_ERROR);
203 
204         uint32_t length;
205         ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
206         IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != SUCCESS, GENERAL_ERROR);
207         IF_TRUE_LOGE_AND_RETURN_VAL(length > readBuffer->len, GENERAL_ERROR);
208 
209         Uint8Array readData = { readBuffer->data, length };
210         if (length > 0) {
211             ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &readData);
212             IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != SUCCESS, GENERAL_ERROR);
213         }
214 
215         ResultCode setAttrResult = SetAttributeUint8Array(attribute, type, readData);
216         IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
217     }
218 
219     return SUCCESS;
220 }
221 
ParseAttributeSerializedMsg(Attribute * attribute,const Uint8Array msg)222 IAM_STATIC ResultCode ParseAttributeSerializedMsg(Attribute *attribute, const Uint8Array msg)
223 {
224     Uint8Array *readBuffer = CreateUint8ArrayBySize(MAX_EXECUTOR_MSG_LEN);
225     IF_TRUE_LOGE_AND_RETURN_VAL(readBuffer == NULL, GENERAL_ERROR);
226 
227     ResultCode result = ParseAttributeSerializedMsgInner(attribute, msg, readBuffer);
228     if (result != SUCCESS) {
229         LOG_ERROR("ParseAttributeSerializedMsgInner fail");
230     }
231     DestroyUint8Array(&readBuffer);
232 
233     return result;
234 }
235 
ParseMultiDataSerializedMsg(const Uint8Array msg,Uint8Array * subMsgData,int * subMsgSize)236 ResultCode ParseMultiDataSerializedMsg(const Uint8Array msg, Uint8Array *subMsgData, int *subMsgSize)
237 {
238     IF_TRUE_LOGE_AND_RETURN_VAL(subMsgSize == NULL, GENERAL_ERROR);
239     IF_TRUE_LOGE_AND_RETURN_VAL(subMsgData == NULL, GENERAL_ERROR);
240 
241     uint32_t readIndex = 0;
242     uint32_t subMsgIndex = 0;
243     while (readIndex < msg.len) {
244         uint32_t length;
245         ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
246         IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != SUCCESS, GENERAL_ERROR);
247 
248         if (length > 0) {
249             IF_TRUE_LOGE_AND_RETURN_VAL(subMsgIndex >= *subMsgSize, GENERAL_ERROR);
250             // subMsgData is freed in outer function
251             subMsgData[subMsgIndex] = (Uint8Array){ Malloc(length), length };
252             IF_TRUE_LOGE_AND_RETURN_VAL(subMsgData[subMsgIndex].data == NULL, GENERAL_ERROR);
253             ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &subMsgData[subMsgIndex]);
254             IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != SUCCESS, GENERAL_ERROR);
255             subMsgIndex++;
256         }
257     }
258 
259     *subMsgSize = subMsgIndex;
260     return SUCCESS;
261 }
262 
263 
CreateEmptyAttribute(void)264 Attribute *CreateEmptyAttribute(void)
265 {
266     AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
267     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
268     (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
269 
270     return attribute;
271 }
272 
CreateAttributeFromSerializedMsg(const Uint8Array msg)273 Attribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
274 {
275     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
276 
277     Attribute *attribute = CreateEmptyAttribute();
278     if (attribute == NULL) {
279         LOG_ERROR("CreateEmptyAttribute failed");
280         return NULL;
281     }
282 
283     ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
284     if (result != SUCCESS) {
285         LOG_ERROR("ParseAttributeSerializedMsg failed");
286         FreeAttribute((Attribute **)&attribute);
287         return NULL;
288     }
289 
290     return attribute;
291 }
292 
GetAttributeSerializedMsg(const Attribute * attributePublic,Uint8Array * retMsg)293 ResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
294 {
295     IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, INVALID_PARAMETERS);
296     IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
297     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
298 
299     const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
300     uint32_t writeIndex = 0;
301     for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
302         Uint8Array *array = attribute->values[i];
303         if (array == NULL) {
304             continue;
305         }
306 
307         ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
308         IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != SUCCESS, GENERAL_ERROR);
309 
310         ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
311         IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
312 
313         if (array->len == 0) {
314             continue;
315         }
316         ResultCode writeDataResult =
317             WriteDataToMsg(retMsg, &writeIndex, *array);
318         IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
319     }
320 
321     retMsg->len = writeIndex;
322     return SUCCESS;
323 }
324 
FreeAttribute(Attribute ** attribute)325 void FreeAttribute(Attribute **attribute)
326 {
327     IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
328     IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
329     AttributeImpl *impl = (AttributeImpl *)*attribute;
330     for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
331         DestroyUint8Array(&impl->values[i]);
332     }
333 
334     IAM_FREE_AND_SET_NULL(*attribute);
335 }
336 
GetAttributeUint32(const Attribute * attribute,AttributeKey key,uint32_t * value)337 ResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
338 {
339     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
340     IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, INVALID_PARAMETERS);
341 
342     uint32_t netOrderValue;
343     Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
344     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
345     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
346     IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), GENERAL_ERROR);
347 
348     *value = Ntohl32(netOrderValue);
349     return SUCCESS;
350 }
351 
SetAttributeUint32(Attribute * attribute,AttributeKey key,const uint32_t value)352 ResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
353 {
354     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
355 
356     uint32_t netOrderValue = Htonl32(value);
357     ResultCode result =
358         SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
359     IF_TRUE_LOGE_AND_RETURN_VAL(result != SUCCESS, GENERAL_ERROR);
360 
361     return result;
362 }
363 
GetAttributeInt32(const Attribute * attribute,AttributeKey key,int32_t * retValue)364 ResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
365 {
366     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
367     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
368 
369     return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
370 }
371 
SetAttributeInt32(Attribute * attribute,AttributeKey key,const int32_t value)372 ResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
373 {
374     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
375 
376     return SetAttributeUint32(attribute, key, (uint32_t)value);
377 }
378 
GetAttributeUint64(const Attribute * attribute,AttributeKey key,uint64_t * retValue)379 ResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
380 {
381     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
382     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
383 
384     uint64_t netOrderValue;
385     Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
386     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
387     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
388     IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), GENERAL_ERROR);
389 
390     *retValue = Ntohl64(netOrderValue);
391     return SUCCESS;
392 }
393 
SetAttributeUint64(Attribute * attribute,AttributeKey key,const uint64_t value)394 ResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
395 {
396     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
397 
398     uint64_t netOrderValue = Htonl64(value);
399     ResultCode setAttrResult =
400         SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
401     IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
402 
403     return SUCCESS;
404 }
405 
GetAttributeUint8Array(const Attribute * attributePub,AttributeKey key,Uint8Array * retData)406 ResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
407 {
408     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
409     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
410     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
411 
412     const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
413 
414     uint32_t attributeIndex;
415     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
416     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
417 
418     if (attribute->values[attributeIndex] == NULL) {
419         LOG_ERROR("data is not set");
420         return GENERAL_ERROR;
421     }
422 
423     if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
424         errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
425             attribute->values[attributeIndex]->len);
426         IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, GENERAL_ERROR);
427     } else {
428         LOG_INFO("the current data is an empty array");
429     }
430     retData->len = attribute->values[attributeIndex]->len;
431 
432     return SUCCESS;
433 }
434 
SetAttributeUint8Array(Attribute * attributePub,AttributeKey key,const Uint8Array data)435 ResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
436 {
437     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
438     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
439 
440     AttributeImpl *attribute = (AttributeImpl *)attributePub;
441 
442     uint32_t attributeIndex;
443     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
444     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
445 
446     DestroyUint8Array(&attribute->values[attributeIndex]);
447     attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
448     if (attribute->values[attributeIndex] == NULL) {
449         LOG_ERROR("CreateUint8ArrayByData fail");
450         return GENERAL_ERROR;
451     }
452 
453     return SUCCESS;
454 }
455 
GetAttributeUint64Array(const Attribute * attribute,AttributeKey key,Uint64Array * retData)456 ResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
457 {
458     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
459     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
460     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
461 
462     Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
463     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
464     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
465     if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
466         LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
467         return GENERAL_ERROR;
468     }
469     Ntohl64Array(retData);
470 
471     retData->len = uint64ArrayData.len / sizeof(uint64_t);
472     return SUCCESS;
473 }
474 
SetAttributeUint64Array(Attribute * attribute,AttributeKey key,const Uint64Array data)475 ResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
476 {
477     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
478     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
479 
480     Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
481     IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, GENERAL_ERROR);
482 
483     ResultCode result = GENERAL_ERROR;
484     do {
485         Htonl64Array(netOrderData);
486         if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
487             LOG_ERROR("netOrderData->len is invalid");
488             break;
489         }
490         result = SetAttributeUint8Array(attribute, key,
491             (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
492         if (result != SUCCESS) {
493             LOG_ERROR("SetAttributeUint8Array fail");
494             break;
495         }
496     } while (0);
497 
498     DestroyUint64Array(&netOrderData);
499     return result;
500 }
501 
GetMultiDataSerializedMsg(Uint8Array * sourceArrayMsg,uint32_t size,Uint8Array * retMsg)502 ResultCode GetMultiDataSerializedMsg(Uint8Array *sourceArrayMsg, uint32_t size, Uint8Array *retMsg)
503 {
504     IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg == NULL, INVALID_PARAMETERS);
505     IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
506     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
507 
508     uint32_t writeIndex = 0;
509     for (uint32_t i = 0; i < size; i++) {
510         IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg[i].data == NULL, GENERAL_ERROR);
511         Uint8Array sourceMsg = sourceArrayMsg[i];
512         if (sourceMsg.len == 0) {
513             continue;
514         }
515         ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, sourceMsg.len);
516         IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
517 
518         ResultCode writeDataResult = WriteDataToMsg(retMsg, &writeIndex, sourceMsg);
519         IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
520     }
521     retMsg->len = writeIndex;
522     return SUCCESS;
523 }
524