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 defines asset-related data structures.
17 
18 use std::collections::HashMap;
19 
20 mod extension;
21 #[macro_use]
22 pub mod macros;
23 
24 impl_enum_trait! {
25     /// An enum type containing the data type definitions for Asset attribute value.
26     #[derive(Eq, PartialEq)]
27     pub enum DataType {
28         /// The data type of Asset attribute value is bool.
29         Bool = 1 << 28,
30 
31         /// The data type of Asset attribute value is uint32.
32         Number = 2 << 28,
33 
34         /// The data type of Asset attribute value is byte array.
35         Bytes = 3 << 28,
36     }
37 }
38 
39 impl_tag_trait! {
40     /// An emum type that indicates the tag of the asset attribute.
41     #[derive(Clone, Copy)]
42     #[derive(Debug)]
43     #[derive(Eq, Hash, PartialEq)]
44     pub enum Tag {
45         /// A tag whose value is a byte array indicating the sensitive user data such as passwords and tokens.
46         Secret = DataType::Bytes as isize | 0x01,
47 
48         /// A tag whose value is a byte array identifying an Asset.
49         Alias = DataType::Bytes as isize | 0x02,
50 
51         /// A tag whose value is a 32-bit unsigned integer indicating when the Asset can be accessed.
52         Accessibility = DataType::Number as isize | 0x03,
53 
54         /// A tag whose value is a bool indicating whether a screen lock password is set for the device.
55         RequirePasswordSet = DataType::Bool as isize | 0x04,
56 
57         /// A tag whose value is a 32-bit unsigned integer indicating
58         /// the user authentication type for Asset access control.
59         AuthType = DataType::Number as isize | 0x05,
60 
61         /// A tag whose value is a 32-bit unsigned integer indicating
62         /// the validity period in seconds of user authentication.
63         AuthValidityPeriod = DataType::Number as isize | 0x06,
64 
65         /// A tag whose value is a byte array indicating the authentication challenge for anti-replay protection.
66         AuthChallenge = DataType::Bytes as isize | 0x07,
67 
68         /// A tag whose value is a byte array indicating the authentication token after a user is verified.
69         AuthToken = DataType::Bytes as isize | 0x08,
70 
71         /// A tag whose value is a 32-bit unsigned integer indicating the type of Asset synchronization.
72         SyncType = DataType::Number as isize | 0x10,
73 
74         /// A tag whose value is a bool indicating whether Asset is stored persistently.
75         IsPersistent = DataType::Bool as isize | 0x11,
76 
77         /// A tag whose value is a byte array indicating the first user-defined Asset data label (not allow to update).
78         DataLabelCritical1 = DataType::Bytes as isize | 0x20,
79 
80         /// A tag whose value is a byte array indicating the second user-defined Asset data label (not allow to update).
81         DataLabelCritical2 = DataType::Bytes as isize | 0x21,
82 
83         /// A tag whose value is a byte array indicating the third user-defined Asset data label (not allow to update).
84         DataLabelCritical3 = DataType::Bytes as isize | 0x22,
85 
86         /// A tag whose value is a byte array indicating the fourth user-defined Asset data label (not allow to update).
87         DataLabelCritical4 = DataType::Bytes as isize | 0x23,
88 
89         /// A tag whose value is a byte array indicating the first user-defined Asset data label (allow to update).
90         DataLabelNormal1 = DataType::Bytes as isize | 0x30,
91 
92         /// A tag whose value is a byte array indicating the second user-defined Asset data label (allow to update).
93         DataLabelNormal2 = DataType::Bytes as isize | 0x31,
94 
95         /// A tag whose value is a byte array indicating the third user-defined Asset data label (allow to update).
96         DataLabelNormal3 = DataType::Bytes as isize | 0x32,
97 
98         /// A tag whose value is a byte array indicating the fourth user-defined Asset data label (allow to update).
99         DataLabelNormal4 = DataType::Bytes as isize | 0x33,
100 
101         /// A local tag whose value is a byte array indicating
102         /// the first user-defined Asset data label (allow to update).
103         /// The information of a local tag will not be synchronized.
104         DataLabelNormalLocal1 = DataType::Bytes as isize | 0x34,
105 
106         /// A local tag whose value is a byte array indicating
107         /// the second user-defined Asset data label (allow to update).
108         /// The information of a local tag will not be synchronized.
109         DataLabelNormalLocal2 = DataType::Bytes as isize | 0x35,
110 
111         /// A local tag whose value is a byte array indicating
112         /// the third user-defined Asset data label (allow to update).
113         /// The information of a local tag will not be synchronized.
114         DataLabelNormalLocal3 = DataType::Bytes as isize | 0x36,
115 
116         /// A local tag whose value is a byte array indicating
117         /// the fourth user-defined Asset data label (allow to update).
118         /// The information of a local tag will not be synchronized.
119         DataLabelNormalLocal4 = DataType::Bytes as isize | 0x37,
120 
121         /// A tag whose value is a 32-bit unsigned integer indicating the return type of the queried Asset.
122         ReturnType = DataType::Number as isize | 0x40,
123 
124         /// A tag whose value is a 32-bit unsigned integer indicating the maximum number of returned Assets in a query.
125         ReturnLimit = DataType::Number as isize | 0x41,
126 
127         /// A tag whose value is a 32-bit unsigned integer indicating the offset of return data in batch query.
128         ReturnOffset = DataType::Number as isize | 0x42,
129 
130         /// A tag whose value is a 32-bit unsigned integer indicating how the query results are sorted.
131         ReturnOrderedBy = DataType::Number as isize | 0x43,
132 
133         /// A tag whose value is a 32-bit unsigned integer indicating the strategy for resolving Asset conflicts.
134         ConflictResolution = DataType::Number as isize | 0x44,
135 
136         /// A tag whose value is a byte array indicating the update time of an Asset.
137         UpdateTime = DataType::Bytes as isize | 0x45,
138 
139         /// A tag whose value is a byte array indicating the update time of an Asset.
140         OperationType = DataType::Number as isize | 0x46,
141 
142         /// A tag whose value is a bool indicating whether the attributes of an asset are required to be encrypted.
143         RequireAttrEncrypted = DataType::Bool as isize | 0x47,
144 
145         /// A tag whose value is a 32-bit unsigned integer indicating the specific user id.
146         UserId = DataType::Number as isize | 0x100,
147     }
148 }
149 
150 /// A type that indicates the secret or attribute value of an Asset tag.
151 #[derive(Clone)]
152 #[derive(Debug)]
153 #[derive(Eq, Hash, PartialEq)]
154 #[repr(C)]
155 pub enum Value {
156     /// Asset attribute value, whose data type is bool.
157     Bool(bool),
158 
159     /// Asset attribute value, whose data type is number.
160     Number(u32),
161 
162     /// Asset attribute value, whose data type is byte array.
163     Bytes(Vec<u8>),
164 }
165 
166 impl Drop for Value {
drop(&mut self)167     fn drop(&mut self) {
168         if let Value::Bytes(bytes) = self {
169             bytes.fill(0);
170         }
171     }
172 }
173 
174 /// A Map type containing tag-value pairs that describe the attributes of an Asset.
175 pub type AssetMap = HashMap<Tag, Value>;
176 
177 impl_enum_trait! {
178     /// An enum type containing the Asset error codes.
179     #[derive(Clone, Copy)]
180     #[derive(Debug)]
181     #[derive(Eq, Hash, PartialEq)]
182     pub enum ErrCode {
183         /// The error code indicates that the caller doesn't have the permission.
184         PermissionDenied = 201,
185 
186         /// The error code indicates that the caller is not system application.
187         NotSystemApplication = 202,
188 
189         /// The error code indicates that the argument is invalid.
190         InvalidArgument = 401,
191 
192         /// The error code indicates that the ASSET service is unavailable.
193         ServiceUnavailable = 24000001,
194 
195         /// The error code indicates that the queried Asset can not be found.
196         NotFound = 24000002,
197 
198         /// The error code indicates that the Asset already exists.
199         Duplicated = 24000003,
200 
201         /// The error code indicates that the access to Asset is denied.
202         AccessDenied = 24000004,
203 
204         /// The error code indicates that the screen lock status mismatches.
205         StatusMismatch = 24000005,
206 
207         /// The error code indicates insufficient memory.
208         OutOfMemory = 24000006,
209 
210         /// The error code indicates that the Asset is corrupted.
211         DataCorrupted = 24000007,
212 
213         /// The error code indicates that the database operation is failed.
214         DatabaseError = 24000008,
215 
216         /// The error code indicates that the cryptography operation is failed.
217         CryptoError = 24000009,
218 
219         /// The error code indicates that the ipc communication is abnormal.
220         IpcError = 24000010,
221 
222         /// The error code indicates that the operation of calling Bundle Manager Service is failed.
223         BmsError = 24000011,
224 
225         /// The error code indicates that the operation of calling OS Account Service is failed.
226         AccountError = 24000012,
227 
228         /// The error code indicates that the operation of calling Access Token Service is failed.
229         AccessTokenError = 24000013,
230 
231         /// The error code indicates that the operation of file is failed.
232         FileOperationError = 24000014,
233 
234         /// The error code indicates that the operation of getting system time failed.
235         GetSystemTimeError = 24000015,
236 
237         /// The error code indicates that the cache exceeds the limit.
238         LimitExceeded = 24000016,
239 
240         /// The error code indicates that the capability is not supported.
241         Unsupported = 24000017,
242     }
243 }
244 
245 /// A struct containing the Asset result code and error message.
246 #[derive(Debug)]
247 pub struct AssetError {
248     /// Error code for error occurred.
249     pub code: ErrCode,
250 
251     /// Error message for error occurred.
252     pub msg: String,
253 }
254 
255 /// Alias of the Asset result type.
256 pub type Result<T> = std::result::Result<T, AssetError>;
257 
258 impl_enum_trait! {
259     /// An enum type indicates when the Asset is accessible.
260     #[repr(C)]
261     #[derive(Debug)]
262     #[derive(Clone, Copy)]
263     #[derive(PartialEq, Eq)]
264     #[derive(Default)]
265     pub enum Accessibility {
266         /// The secret value in the Asset can only be accessed after the device power on.
267         DevicePowerOn = 0,
268 
269         /// The secret value in the Asset can only be accessed after the device is first unlocked.
270         #[default]
271         DeviceFirstUnlocked = 1,
272 
273         /// The secret value in the Asset can only be accessed while the device is unlocked.
274         DeviceUnlocked = 2,
275     }
276 }
277 
278 impl_enum_trait! {
279     /// An enum type indicates the user authentication type for Asset access control.
280     #[derive(Debug)]
281     #[derive(Clone, Copy)]
282     #[derive(PartialEq, Eq)]
283     #[derive(Default)]
284     pub enum AuthType {
285         /// The access to an Asset doesn't require user authentication.
286         #[default]
287         None = 0x00,
288 
289         /// The access to an Asset requires user authentication using either PIN/pattern/password or biometric traits.
290         Any = 0xFF,
291     }
292 }
293 
294 impl_enum_trait! {
295     /// An enum type indicates the type of Asset synchronization.
296     #[derive(Debug)]
297     #[derive(Clone, Copy)]
298     #[derive(PartialEq, Eq)]
299     #[derive(Default)]
300     pub enum SyncType {
301         /// An Asset with this attribute value is never allowed to be transferred out.
302         #[default]
303         Never = 0,
304 
305         /// An Asset with this attribute value can only be restored to the device from which it was transferred out.
306         ThisDevice = 1 << 0,
307 
308         /// An Asset with this attribute value can only be transferred out to a trusted device (user authorized).
309         TrustedDevice = 1 << 1,
310 
311         /// An Asset with this attribute value can only be transferred out to a trusted device (user authorized).
312         TrustedAccount = 1 << 2,
313     }
314 }
315 
316 impl_enum_trait! {
317     /// An enum type indicates the strategy for conflict resolution when handling duplicated Asset alias.
318     #[derive(Default)]
319     pub enum ConflictResolution {
320         /// Directly overwrite an Asset with duplicated alias when a conflict is detected.
321         Overwrite = 0,
322 
323         /// Throw an error so that the caller can take measures when a conflict is detected.
324         #[default]
325         ThrowError = 1,
326     }
327 }
328 
329 impl_enum_trait! {
330     /// An enum type indicates the return type of the queried Asset.
331     #[derive(Debug)]
332     #[derive(Clone, Copy)]
333     #[derive(PartialEq, Eq)]
334     #[derive(Default)]
335     pub enum LocalStatus {
336         /// Specify that the return data should contain both secret value and attributes.
337         #[default]
338         Local = 0,
339 
340         /// Specify that the return data contains only attributes.
341         Cloud = 1 << 0,
342     }
343 }
344 
345 impl_enum_trait! {
346     /// An enum type indicates the return type of the queried Asset.
347     #[derive(Debug)]
348     #[derive(Clone, Copy)]
349     #[derive(PartialEq, Eq)]
350     #[derive(Default)]
351     pub enum SyncStatus {
352         /// Specify that the return data should contain both secret value and attributes.
353         #[default]
354         NoNeedSync = 0,
355 
356         /// Specify that the return data contains only attributes.
357         SyncAdd = 1 << 0,
358 
359         /// Specify that the return data contains only attributes.
360         SyncDel = 1 << 1,
361 
362         /// Specify that the return data contains only attributes.
363         SyncUpdate = 1 << 2,
364     }
365 }
366 
367 impl_enum_trait! {
368     /// An enum type indicates the return type of the queried Asset.
369     #[derive(Default)]
370     pub enum ReturnType {
371         /// Specify that the return data should contain both secret value and attributes.
372         All = 0,
373 
374         /// Specify that the return data contains only attributes.
375         #[default]
376         Attributes = 1,
377     }
378 }
379 
380 impl_enum_trait! {
381     /// An enum type indicates the return type of the queried Asset.
382     #[derive(Default)]
383     pub enum OperationType {
384         /// Trigger Sync.
385         #[default]
386         NeedSync = 0,
387 
388         /// Logout to clean cloud flag.
389         NeedLogout = 1,
390 
391         /// Delete cloud data.
392         NeedDeleteCloudData = 2,
393     }
394 }
395 
396 /// Expended abililty for HashMap.
397 pub trait Extension<K> {
398     /// Insert an attribute into the collection.
insert_attr(&mut self, key: K, value: impl Conversion)399     fn insert_attr(&mut self, key: K, value: impl Conversion);
400 
401     /// Get an attribute of bool type from the collection.
get_bool_attr(&self, key: &K) -> Result<bool>402     fn get_bool_attr(&self, key: &K) -> Result<bool>;
403 
404     /// Get an attribute of enum type from the collection.
get_enum_attr<T: TryFrom<u32, Error = AssetError>>(&self, key: &K) -> Result<T>405     fn get_enum_attr<T: TryFrom<u32, Error = AssetError>>(&self, key: &K) -> Result<T>;
406 
407     /// Get an attribute of number type from the collection.
get_num_attr(&self, key: &K) -> Result<u32>408     fn get_num_attr(&self, key: &K) -> Result<u32>;
409 
410     /// Get an attribute of bytes type from the collection.
get_bytes_attr(&self, key: &K) -> Result<&Vec<u8>>411     fn get_bytes_attr(&self, key: &K) -> Result<&Vec<u8>>;
412 }
413 
414 /// Conversion between a specific type and the Asset Value type.
415 pub trait Conversion {
416     /// Get the data type of Asset Enum type.
data_type(&self) -> DataType417     fn data_type(&self) -> DataType;
418 
419     /// Convert the Asset Enum type to the Value variant.
into_value(self) -> Value420     fn into_value(self) -> Value;
421 }
422