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