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 //! This module is used to verify the validity of asset attributes.
17
18 use asset_common::{is_user_id_exist, ROOT_USER_UPPERBOUND};
19 use asset_definition::{
20 log_throw_error, Accessibility, AssetMap, AuthType, ConflictResolution, Conversion, ErrCode, OperationType, Result,
21 ReturnType, Tag, Value,
22 };
23
24 use crate::operations::common::{CRITICAL_LABEL_ATTRS, NORMAL_LABEL_ATTRS, NORMAL_LOCAL_LABEL_ATTRS};
25
26 const MIN_NUMBER_VALUE: u32 = 0;
27 const MAX_RETURN_LIMIT: u32 = 0x10000; // 65536
28 const MAX_AUTH_VALID_PERIOD: u32 = 600; // 10min
29
30 const MIN_ARRAY_SIZE: usize = 0;
31 const MAX_SECRET_SIZE: usize = 1024;
32 const MAX_TIME_SIZE: usize = 1024;
33
34 const MAX_ALIAS_SIZE: usize = 256;
35 pub const MAX_LABEL_SIZE: usize = 2048;
36
37 const AUTH_TOKEN_SIZE: usize = 280;
38 const CHALLENGE_SIZE: usize = 32;
39 const SYNC_TYPE_MIN_BITS: u32 = 0;
40 const SYNC_TYPE_MAX_BITS: u32 = 3;
41
check_data_type(tag: &Tag, value: &Value) -> Result<()>42 fn check_data_type(tag: &Tag, value: &Value) -> Result<()> {
43 if tag.data_type() != value.data_type() {
44 return log_throw_error!(
45 ErrCode::InvalidArgument,
46 "[FATAL]The data type[{}] of the tag[{}] does not match that of the value.",
47 value.data_type(),
48 tag
49 );
50 }
51 Ok(())
52 }
53
check_array_size(tag: &Tag, value: &Value, min: usize, max: usize) -> Result<()>54 fn check_array_size(tag: &Tag, value: &Value, min: usize, max: usize) -> Result<()> {
55 let Value::Bytes(v) = value else {
56 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a bytes.", tag);
57 };
58 if v.len() > max || v.len() <= min {
59 return log_throw_error!(
60 ErrCode::InvalidArgument,
61 "[FATAL]The array length[{}] of Tag[{}], exceeds the valid range.",
62 v.len(),
63 tag
64 );
65 }
66 Ok(())
67 }
68
check_enum_variant<T: TryFrom<u32>>(tag: &Tag, value: &Value) -> Result<()>69 fn check_enum_variant<T: TryFrom<u32>>(tag: &Tag, value: &Value) -> Result<()> {
70 let Value::Number(n) = value else {
71 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a number.", tag);
72 };
73 if T::try_from(*n).is_err() {
74 return log_throw_error!(
75 ErrCode::InvalidArgument,
76 "[FATAL]The value[{}] of Tag[{}] is not a legal enumeration variant",
77 *n,
78 tag
79 );
80 }
81 Ok(())
82 }
83
check_valid_bits(tag: &Tag, value: &Value, min_bits: u32, max_bits: u32) -> Result<()>84 fn check_valid_bits(tag: &Tag, value: &Value, min_bits: u32, max_bits: u32) -> Result<()> {
85 let Value::Number(n) = value else {
86 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a number.", tag);
87 };
88 if *n >= 2_u32.pow(max_bits) || *n < (2_u32.pow(min_bits) - 1) {
89 // 2: binary system
90 return log_throw_error!(
91 ErrCode::InvalidArgument,
92 "[FATAL]The value[{}] of Tag[{}] is not in the valid bit number.",
93 *n,
94 tag
95 );
96 }
97 Ok(())
98 }
99
check_number_range(tag: &Tag, value: &Value, min: u32, max: u32) -> Result<()>100 fn check_number_range(tag: &Tag, value: &Value, min: u32, max: u32) -> Result<()> {
101 let Value::Number(n) = value else {
102 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a number.", tag);
103 };
104 if *n <= min || *n > max {
105 return log_throw_error!(
106 ErrCode::InvalidArgument,
107 "[FATAL]The value[{}] of Tag[{}] is not in the valid number range.",
108 *n,
109 tag
110 );
111 }
112 Ok(())
113 }
114
check_tag_range(tag: &Tag, value: &Value, tags: &[Tag]) -> Result<()>115 fn check_tag_range(tag: &Tag, value: &Value, tags: &[Tag]) -> Result<()> {
116 let Value::Number(n) = value else {
117 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a number.", tag);
118 };
119 match Tag::try_from(*n) {
120 Ok(value) if tags.contains(&value) => Ok(()),
121 _ => {
122 log_throw_error!(
123 ErrCode::InvalidArgument,
124 "[FATAL]The value[{}] of Tag[{}] is not in the valid tag range.",
125 *n,
126 tag
127 )
128 },
129 }
130 }
131
check_user_id(tag: &Tag, value: &Value) -> Result<()>132 fn check_user_id(tag: &Tag, value: &Value) -> Result<()> {
133 check_number_range(tag, value, ROOT_USER_UPPERBOUND, i32::MAX as u32)?;
134 let Value::Number(n) = value else {
135 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][{}] is not a number.", tag);
136 };
137 match is_user_id_exist(*n as i32) {
138 Ok(res) if res => Ok(()),
139 Ok(_) => log_throw_error!(ErrCode::InvalidArgument, "[FATAL]The user id [{}] is not exist.", *n),
140 Err(e) => Err(e),
141 }
142 }
143
check_data_value(tag: &Tag, value: &Value) -> Result<()>144 fn check_data_value(tag: &Tag, value: &Value) -> Result<()> {
145 match tag {
146 Tag::Secret => check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_SECRET_SIZE),
147 Tag::Alias => check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_ALIAS_SIZE),
148 Tag::Accessibility => check_enum_variant::<Accessibility>(tag, value),
149 Tag::RequirePasswordSet | Tag::IsPersistent | Tag::RequireAttrEncrypted => Ok(()),
150 Tag::AuthType => check_enum_variant::<AuthType>(tag, value),
151 Tag::AuthValidityPeriod => check_number_range(tag, value, MIN_NUMBER_VALUE, MAX_AUTH_VALID_PERIOD),
152 Tag::AuthChallenge => check_array_size(tag, value, CHALLENGE_SIZE - 1, CHALLENGE_SIZE),
153 Tag::AuthToken => check_array_size(tag, value, AUTH_TOKEN_SIZE - 1, AUTH_TOKEN_SIZE),
154 Tag::SyncType => check_valid_bits(tag, value, SYNC_TYPE_MIN_BITS, SYNC_TYPE_MAX_BITS),
155 Tag::ConflictResolution => check_enum_variant::<ConflictResolution>(tag, value),
156 Tag::DataLabelCritical1 | Tag::DataLabelCritical2 | Tag::DataLabelCritical3 | Tag::DataLabelCritical4 => {
157 check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_LABEL_SIZE)
158 },
159 Tag::DataLabelNormal1 | Tag::DataLabelNormal2 | Tag::DataLabelNormal3 | Tag::DataLabelNormal4 => {
160 check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_LABEL_SIZE)
161 },
162 Tag::DataLabelNormalLocal1
163 | Tag::DataLabelNormalLocal2
164 | Tag::DataLabelNormalLocal3
165 | Tag::DataLabelNormalLocal4 => check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_LABEL_SIZE),
166 Tag::ReturnType => check_enum_variant::<ReturnType>(tag, value),
167 Tag::ReturnLimit => check_number_range(tag, value, MIN_NUMBER_VALUE, MAX_RETURN_LIMIT),
168 Tag::ReturnOffset => Ok(()),
169 Tag::ReturnOrderedBy => {
170 check_tag_range(tag, value, &[CRITICAL_LABEL_ATTRS, NORMAL_LABEL_ATTRS, NORMAL_LOCAL_LABEL_ATTRS].concat())
171 },
172 Tag::UserId => check_user_id(tag, value),
173 Tag::UpdateTime => check_array_size(tag, value, MIN_ARRAY_SIZE, MAX_TIME_SIZE),
174 Tag::OperationType => check_enum_variant::<OperationType>(tag, value),
175 }
176 }
177
check_value_validity(attrs: &AssetMap) -> Result<()>178 pub(crate) fn check_value_validity(attrs: &AssetMap) -> Result<()> {
179 for (tag, value) in attrs {
180 check_data_type(tag, value)?;
181 check_data_value(tag, value)?;
182 }
183 Ok(())
184 }
185
check_required_tags(attrs: &AssetMap, required_tags: &[Tag]) -> Result<()>186 pub(crate) fn check_required_tags(attrs: &AssetMap, required_tags: &[Tag]) -> Result<()> {
187 for tag in required_tags {
188 if !attrs.contains_key(tag) {
189 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL]The required tag [{}] is missing.", tag);
190 }
191 }
192 Ok(())
193 }
194
check_tag_validity(attrs: &AssetMap, valid_tags: &[Tag]) -> Result<()>195 pub(crate) fn check_tag_validity(attrs: &AssetMap, valid_tags: &[Tag]) -> Result<()> {
196 for tag in attrs.keys() {
197 if !valid_tags.contains(tag) {
198 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL]The tag [{}] is illegal.", tag);
199 }
200 }
201 Ok(())
202 }
203