• 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 };
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 
CreateEmptyAttribute(void)263 Attribute *CreateEmptyAttribute(void)
264 {
265     AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
266     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
267     (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
268 
269     return attribute;
270 }
271 
CreateAttributeFromSerializedMsg(const Uint8Array msg)272 Attribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
273 {
274     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
275 
276     Attribute *attribute = CreateEmptyAttribute();
277     if (attribute == NULL) {
278         LOG_ERROR("CreateEmptyAttribute failed");
279         return NULL;
280     }
281 
282     ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
283     if (result != SUCCESS) {
284         LOG_ERROR("ParseAttributeSerializedMsg failed");
285         FreeAttribute((Attribute **)&attribute);
286         return NULL;
287     }
288 
289     return attribute;
290 }
291 
GetAttributeSerializedMsg(const Attribute * attributePublic,Uint8Array * retMsg)292 ResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
293 {
294     IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, INVALID_PARAMETERS);
295     IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
296     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
297 
298     const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
299     uint32_t writeIndex = 0;
300     for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
301         Uint8Array *array = attribute->values[i];
302         if (array == NULL) {
303             continue;
304         }
305 
306         ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
307         IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != SUCCESS, GENERAL_ERROR);
308 
309         ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
310         IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
311 
312         if (array->len == 0) {
313             continue;
314         }
315         ResultCode writeDataResult =
316             WriteDataToMsg(retMsg, &writeIndex, *array);
317         IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
318     }
319 
320     retMsg->len = writeIndex;
321     return SUCCESS;
322 }
323 
FreeAttribute(Attribute ** attribute)324 void FreeAttribute(Attribute **attribute)
325 {
326     IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
327     IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
328     AttributeImpl *impl = (AttributeImpl *)*attribute;
329     for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
330         DestroyUint8Array(&impl->values[i]);
331     }
332 
333     IAM_FREE_AND_SET_NULL(*attribute);
334 }
335 
GetAttributeUint32(const Attribute * attribute,AttributeKey key,uint32_t * value)336 ResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
337 {
338     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
339     IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, INVALID_PARAMETERS);
340 
341     uint32_t netOrderValue;
342     Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
343     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
344     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
345     IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), GENERAL_ERROR);
346 
347     *value = Ntohl32(netOrderValue);
348     return SUCCESS;
349 }
350 
SetAttributeUint32(Attribute * attribute,AttributeKey key,const uint32_t value)351 ResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
352 {
353     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
354 
355     uint32_t netOrderValue = Htonl32(value);
356     ResultCode result =
357         SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
358     IF_TRUE_LOGE_AND_RETURN_VAL(result != SUCCESS, GENERAL_ERROR);
359 
360     return result;
361 }
362 
GetAttributeInt32(const Attribute * attribute,AttributeKey key,int32_t * retValue)363 ResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
364 {
365     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
366     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
367 
368     return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
369 }
370 
SetAttributeInt32(Attribute * attribute,AttributeKey key,const int32_t value)371 ResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
372 {
373     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
374 
375     return SetAttributeUint32(attribute, key, (uint32_t)value);
376 }
377 
GetAttributeUint64(const Attribute * attribute,AttributeKey key,uint64_t * retValue)378 ResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
379 {
380     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
381     IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
382 
383     uint64_t netOrderValue;
384     Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
385     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
386     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
387     IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), GENERAL_ERROR);
388 
389     *retValue = Ntohl64(netOrderValue);
390     return SUCCESS;
391 }
392 
SetAttributeUint64(Attribute * attribute,AttributeKey key,const uint64_t value)393 ResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
394 {
395     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
396 
397     uint64_t netOrderValue = Htonl64(value);
398     ResultCode setAttrResult =
399         SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
400     IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
401 
402     return SUCCESS;
403 }
404 
GetAttributeUint8Array(const Attribute * attributePub,AttributeKey key,Uint8Array * retData)405 ResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
406 {
407     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
408     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
409     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
410 
411     const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
412 
413     uint32_t attributeIndex;
414     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
415     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
416 
417     if (attribute->values[attributeIndex] == NULL) {
418         LOG_ERROR("data is not set");
419         return GENERAL_ERROR;
420     }
421 
422     if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
423         errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
424             attribute->values[attributeIndex]->len);
425         IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, GENERAL_ERROR);
426     } else {
427         LOG_INFO("the current data is an empty array");
428     }
429     retData->len = attribute->values[attributeIndex]->len;
430 
431     return SUCCESS;
432 }
433 
SetAttributeUint8Array(Attribute * attributePub,AttributeKey key,const Uint8Array data)434 ResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
435 {
436     IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
437     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
438 
439     AttributeImpl *attribute = (AttributeImpl *)attributePub;
440 
441     uint32_t attributeIndex;
442     ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
443     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
444 
445     DestroyUint8Array(&attribute->values[attributeIndex]);
446     attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
447     if (attribute->values[attributeIndex] == NULL) {
448         LOG_ERROR("CreateUint8ArrayByData fail");
449         return GENERAL_ERROR;
450     }
451 
452     return SUCCESS;
453 }
454 
GetAttributeUint64Array(const Attribute * attribute,AttributeKey key,Uint64Array * retData)455 ResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
456 {
457     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
458     IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
459     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
460 
461     Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
462     ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
463     IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
464     if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
465         LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
466         return GENERAL_ERROR;
467     }
468     Ntohl64Array(retData);
469 
470     retData->len = uint64ArrayData.len / sizeof(uint64_t);
471     return SUCCESS;
472 }
473 
SetAttributeUint64Array(Attribute * attribute,AttributeKey key,const Uint64Array data)474 ResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
475 {
476     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
477     IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
478 
479     Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
480     IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, GENERAL_ERROR);
481 
482     ResultCode result = GENERAL_ERROR;
483     do {
484         Htonl64Array(netOrderData);
485         if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
486             LOG_ERROR("netOrderData->len is invalid");
487             break;
488         }
489         result = SetAttributeUint8Array(attribute, key,
490             (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
491         if (result != SUCCESS) {
492             LOG_ERROR("SetAttributeUint8Array fail");
493             break;
494         }
495     } while (0);
496 
497     DestroyUint64Array(&netOrderData);
498     return result;
499 }
500 
GetMultiDataSerializedMsg(Uint8Array * sourceArrayMsg,uint32_t size,Uint8Array * retMsg)501 ResultCode GetMultiDataSerializedMsg(Uint8Array *sourceArrayMsg, uint32_t size, Uint8Array *retMsg)
502 {
503     IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg == NULL, INVALID_PARAMETERS);
504     IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
505     IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
506 
507     uint32_t writeIndex = 0;
508     for (uint32_t i = 0; i < size; i++) {
509         IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg[i].data == NULL, GENERAL_ERROR);
510         Uint8Array sourceMsg = sourceArrayMsg[i];
511         if (sourceMsg.len == 0) {
512             continue;
513         }
514         ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, sourceMsg.len);
515         IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
516 
517         ResultCode writeDataResult = WriteDataToMsg(retMsg, &writeIndex, sourceMsg);
518         IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
519     }
520     retMsg->len = writeIndex;
521     return SUCCESS;
522 }
523