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