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