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