• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "asset_napi_check.h"
17 
18 #include <algorithm>
19 #include <climits>
20 #include <cmath>
21 #include <functional>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include "securec.h"
26 
27 #include "asset_log.h"
28 #include "asset_system_type.h"
29 
30 #include "asset_napi_common.h"
31 
32 namespace OHOS {
33 namespace Security {
34 namespace Asset {
35 namespace {
36 
37 #define MIN_ARRAY_SIZE 0
38 #define MAX_SECRET_SIZE 1024
39 #define MAX_ALIAS_SIZE 256
40 #define MIN_NUMBER_VALUE 0
41 #define MAX_AUTH_VALID_PERIOD 600
42 #define CHALLENGE_SIZE 32
43 #define MAX_AUTH_TOKEN_SIZE 1024
44 #define MAX_LABEL_SIZE 2048
45 #define MAX_RETURN_LIMIT 0x10000
46 #define SYNC_TYPE_MIN_BITS 0
47 #define SYNC_TYPE_MAX_BITS 3
48 #define ROOT_USER_UPPERBOUND 99
49 #define MAX_TIME_SIZE 1024
50 #define SYSTEM_USER_ID_MAX 99
51 #define BINARY_BASE 2
52 #define MIN_GROUP_ID_SIZE 7
53 #define MAX_GROUP_ID_SIZE 127
54 
CheckArraySize(const napi_env env,const AssetAttr & attr,uint32_t min,uint32_t max,uint32_t errorCode)55 napi_value CheckArraySize(const napi_env env, const AssetAttr &attr, uint32_t min, uint32_t max, uint32_t errorCode)
56 {
57     if (attr.value.blob.size > max || attr.value.blob.size <= min) {
58         RETURN_JS_ERROR(env, errorCode, "Value byte length[%u] of tag[asset.Tag.%s] is out of range[%u, %u].",
59             attr.value.blob.size, TAG_MAP.at(attr.tag),  min + 1, max);
60     }
61     return nullptr;
62 }
63 
CheckEnumVariant(const napi_env env,const AssetAttr & attr,const std::vector<uint32_t> & enumVec,uint32_t errorCode)64 napi_value CheckEnumVariant(const napi_env env, const AssetAttr &attr, const std::vector<uint32_t> &enumVec,
65     uint32_t errorCode)
66 {
67     auto it = std::find(enumVec.begin(), enumVec.end(), attr.value.u32);
68     if (it == enumVec.end()) {
69         RETURN_JS_ERROR(env, errorCode, "Value[%u] of tag[asset.Tag.%s] is an illegal enumeration variant.",
70             attr.value.u32, TAG_MAP.at(attr.tag));
71     }
72     return nullptr;
73 }
74 
CheckNumberRange(const napi_env env,const AssetAttr & attr,uint32_t min,uint32_t max,uint32_t errorCode)75 napi_value CheckNumberRange(const napi_env env, const AssetAttr &attr, uint32_t min, uint32_t max, uint32_t errorCode)
76 {
77     if (attr.value.u32 > max || attr.value.u32 <= min) {
78         RETURN_JS_ERROR(env, errorCode, "Value[%u] of tag[asset.Tag.%s] is out of range[%u, %u].",
79             attr.value.u32, TAG_MAP.at(attr.tag), min, max);
80     }
81     return nullptr;
82 }
83 
CheckValidBits(const napi_env env,const AssetAttr & attr,uint32_t minBits,uint32_t maxBits,uint32_t errorCode)84 napi_value CheckValidBits(const napi_env env, const AssetAttr &attr, uint32_t minBits, uint32_t maxBits,
85     uint32_t errorCode)
86 {
87     if (attr.value.u32 >= pow(BINARY_BASE, maxBits) || attr.value.u32 < pow(BINARY_BASE, minBits) - 1) {
88         RETURN_JS_ERROR(env, errorCode, "Value[%u] of tag[asset.Tag.%s] has bit count out of range[%u, %u].",
89             attr.value.u32, TAG_MAP.at(attr.tag), minBits + 1, maxBits);
90     }
91     return nullptr;
92 }
93 
CheckTagRange(const napi_env env,const AssetAttr & attr,const std::vector<uint32_t> & tags,uint32_t errorCode)94 napi_value CheckTagRange(const napi_env env, const AssetAttr &attr, const std::vector<uint32_t> &tags,
95     uint32_t errorCode)
96 {
97     auto it = std::find(tags.begin(), tags.end(), attr.value.u32);
98     if (it == tags.end()) {
99         RETURN_JS_ERROR(env, errorCode, "Value[0x%X] of tag[asset.Tag.(%s)] is not tags allowed for sorting, "
100             "which should start with \"DATA_LABEL\".", attr.value.u32, TAG_MAP.at(attr.tag));
101     }
102     return nullptr;
103 }
104 
105 struct CheckContinuousRange {
106     std::function<napi_value(const napi_env, const AssetAttr &, uint32_t, uint32_t, uint32_t)> funcPtr;
107     uint32_t min;
108     uint32_t max;
109 };
110 
111 const std::unordered_map<uint32_t, CheckContinuousRange> CHECK_CONTINOUS_RANGE_FUNC_MAP = {
112     { SEC_ASSET_TAG_SECRET, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_SECRET_SIZE } },
113     { SEC_ASSET_TAG_ALIAS, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_ALIAS_SIZE } },
114     { SEC_ASSET_TAG_AUTH_VALIDITY_PERIOD, { &CheckNumberRange, MIN_NUMBER_VALUE, MAX_AUTH_VALID_PERIOD } },
115     { SEC_ASSET_TAG_AUTH_CHALLENGE, { &CheckArraySize, CHALLENGE_SIZE - 1, CHALLENGE_SIZE } },
116     { SEC_ASSET_TAG_AUTH_TOKEN, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_AUTH_TOKEN_SIZE } },
117     { SEC_ASSET_TAG_SYNC_TYPE, { &CheckValidBits, SYNC_TYPE_MIN_BITS, SYNC_TYPE_MAX_BITS } },
118     { SEC_ASSET_TAG_DATA_LABEL_CRITICAL_1, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
119     { SEC_ASSET_TAG_DATA_LABEL_CRITICAL_2, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
120     { SEC_ASSET_TAG_DATA_LABEL_CRITICAL_3, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
121     { SEC_ASSET_TAG_DATA_LABEL_CRITICAL_4, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
122     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_1, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
123     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_2, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
124     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_3, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
125     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_4, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
126     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_LOCAL_1, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
127     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_LOCAL_2, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
128     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_LOCAL_3, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
129     { SEC_ASSET_TAG_DATA_LABEL_NORMAL_LOCAL_4, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_LABEL_SIZE } },
130     { SEC_ASSET_TAG_RETURN_LIMIT, { &CheckNumberRange, MIN_NUMBER_VALUE, MAX_RETURN_LIMIT } },
131     { SEC_ASSET_TAG_GROUP_ID, { &CheckArraySize, MIN_GROUP_ID_SIZE, MAX_GROUP_ID_SIZE } },
132     { SEC_ASSET_TAG_USER_ID, { &CheckNumberRange, ROOT_USER_UPPERBOUND, INT32_MAX } },
133     { SEC_ASSET_TAG_UPDATE_TIME, { &CheckArraySize, MIN_ARRAY_SIZE, MAX_TIME_SIZE } }
134 };
135 
136 struct CheckDiscreteRange {
137     std::function<napi_value(const napi_env, const AssetAttr &, const std::vector<uint32_t> &, uint32_t)> funcPtr;
138     const std::vector<uint32_t> validRange;
139 };
140 
141 const std::unordered_map<uint32_t, CheckDiscreteRange> CHECK_DISCRETE_RANGE_FUNC_MAP = {
142     { SEC_ASSET_TAG_ACCESSIBILITY, { &CheckEnumVariant, ASSET_ACCESSIBILITY_VEC } },
143     { SEC_ASSET_TAG_AUTH_TYPE, { &CheckEnumVariant, ASSET_AUTH_TYPE_VEC } },
144     { SEC_ASSET_TAG_CONFLICT_RESOLUTION, { &CheckEnumVariant, ASSET_CONFLICT_RESOLUTION_VEC } },
145     { SEC_ASSET_TAG_RETURN_TYPE, { &CheckEnumVariant, ASSET_RETURN_TYPE_VEC } },
146     { SEC_ASSET_TAG_RETURN_ORDERED_BY, { &CheckTagRange, ASSET_RETURN_ORDER_BY_TAGS } },
147     { SEC_ASSET_TAG_WRAP_TYPE, { &CheckEnumVariant, ASSET_WRAP_TYPE_VEC } }
148 };
149 
150 } // anonymous namespace
151 
CheckAssetRequiredTag(const napi_env env,const std::vector<AssetAttr> & attrs,const std::vector<uint32_t> & requiredTags,uint32_t errorCode)152 napi_value CheckAssetRequiredTag(const napi_env env, const std::vector<AssetAttr> &attrs,
153     const std::vector<uint32_t> &requiredTags, uint32_t errorCode)
154 {
155     for (uint32_t requiredTag : requiredTags) {
156         auto it = std::find_if(attrs.begin(), attrs.end(), [requiredTag](const AssetAttr &attr) {
157             return attr.tag == requiredTag;
158         });
159         if (it == attrs.end()) {
160             RETURN_JS_ERROR(env, errorCode, "Missing required tag[asset.Tag.%s].", TAG_MAP.at(requiredTag));
161         }
162     }
163     return nullptr;
164 }
165 
CheckAssetTagValidity(const napi_env env,const std::vector<AssetAttr> & attrs,const std::vector<uint32_t> & validTags,uint32_t errorCode)166 napi_value CheckAssetTagValidity(const napi_env env, const std::vector<AssetAttr> &attrs,
167     const std::vector<uint32_t> &validTags, uint32_t errorCode)
168 {
169     for (AssetAttr attr : attrs) {
170         if (std::count(validTags.begin(), validTags.end(), attr.tag) == 0) {
171             RETURN_JS_ERROR(env, errorCode, "Unsupported tag[asset.Tag.%s] for the function.", TAG_MAP.at(attr.tag));
172         }
173     }
174     return nullptr;
175 }
176 
CheckAssetValueValidity(const napi_env env,const std::vector<AssetAttr> & attrs,uint32_t errorCode)177 napi_value CheckAssetValueValidity(const napi_env env, const std::vector<AssetAttr> &attrs, uint32_t errorCode)
178 {
179     napi_value error = nullptr;
180     for (auto attr : attrs) {
181         if (CHECK_CONTINOUS_RANGE_FUNC_MAP.find(attr.tag) != CHECK_CONTINOUS_RANGE_FUNC_MAP.end()) {
182             auto checkRange = CHECK_CONTINOUS_RANGE_FUNC_MAP.at(attr.tag);
183             error = checkRange.funcPtr(env, attr, checkRange.min, checkRange.max, errorCode);
184             if (error != nullptr) {
185                 return error;
186             }
187         }
188         if (CHECK_DISCRETE_RANGE_FUNC_MAP.find(attr.tag) != CHECK_DISCRETE_RANGE_FUNC_MAP.end()) {
189             auto checkRange = CHECK_DISCRETE_RANGE_FUNC_MAP.at(attr.tag);
190             error = checkRange.funcPtr(env, attr, checkRange.validRange, errorCode);
191             if (error != nullptr) {
192                 return error;
193             }
194         }
195     }
196     return error;
197 }
198 
199 } // Asset
200 } // Security
201 } // OHOS
202