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