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 use std::ffi::{c_char, CString};
17 use std::ptr;
18 
19 use asset_common::{CallingInfo, OwnerType};
20 use asset_crypto_manager::{crypto::*, crypto_manager::*, secret_key::*};
21 use asset_definition::{Accessibility, AuthType, ErrCode};
22 
23 pub const AAD_SIZE: u32 = 8;
24 
25 #[repr(C)]
26 struct TokenInfoParams {
27     dcaps_num: i32,
28     perms_num: i32,
29     acls_num: i32,
30     dcaps: *const *const c_char,
31     perms: *const *const c_char,
32     acls: *const *const c_char,
33     process_name: *const c_char,
34     apl_str: *const c_char,
35 }
36 
37 extern "C" {
GetAccessTokenId(token_info: *mut TokenInfoParams) -> u6438     fn GetAccessTokenId(token_info: *mut TokenInfoParams) -> u64;
SetSelfTokenID(token_id: u64) -> i3239     fn SetSelfTokenID(token_id: u64) -> i32;
40 }
41 
42 /// Init access token ID for current process
grant_self_permission() -> i3243 fn grant_self_permission() -> i32 {
44     let perms_str = CString::new("ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS").unwrap();
45     let name = CString::new("asset_bin_test").unwrap();
46     let apl = CString::new("system_basic").unwrap();
47     let mut param = TokenInfoParams {
48         dcaps_num: 0,
49         perms_num: 1,
50         acls_num: 0,
51         dcaps: ptr::null(),
52         perms: &perms_str.as_ptr(),
53         acls: ptr::null(),
54         process_name: name.as_ptr(),
55         apl_str: apl.as_ptr(),
56     };
57 
58     unsafe {
59         let token_id = GetAccessTokenId(&mut param as *mut TokenInfoParams);
60         SetSelfTokenID(token_id)
61     }
62 }
63 
64 #[test]
generate_and_delete()65 fn generate_and_delete() {
66     assert_eq!(0, grant_self_permission());
67     let calling_info = CallingInfo::new(0, OwnerType::Native, vec![b'2']);
68     let secret_key =
69         SecretKey::new_without_alias(&calling_info, AuthType::None, Accessibility::DevicePowerOn, false).unwrap();
70     secret_key.generate().unwrap();
71     secret_key.exists().unwrap();
72     let _ = SecretKey::delete_by_owner(&calling_info);
73     assert!(secret_key.delete().is_ok())
74 }
75 
76 #[test]
encrypt_and_decrypt()77 fn encrypt_and_decrypt() {
78     assert_eq!(0, grant_self_permission());
79     // generate key
80     let calling_info = CallingInfo::new(0, OwnerType::Native, vec![b'2']);
81     let secret_key =
82         SecretKey::new_without_alias(&calling_info, AuthType::None, Accessibility::DevicePowerOn, false).unwrap();
83     secret_key.generate().unwrap();
84 
85     // encrypt data
86     let msg = vec![1, 2, 3, 4, 5, 6];
87     let aad = vec![0; AAD_SIZE as usize];
88     let cipher = Crypto::encrypt(&secret_key, &msg, &aad).unwrap();
89     assert!(!cipher.eq(&msg));
90 
91     // decrypt data
92     let plaintext = Crypto::decrypt(&secret_key, &cipher, &aad).unwrap();
93     assert!(plaintext.eq(&msg));
94 
95     // delete key
96     let _ = secret_key.delete();
97 }
98 
99 #[test]
crypto_init()100 fn crypto_init() {
101     assert_eq!(0, grant_self_permission());
102     let calling_info = CallingInfo::new(0, OwnerType::Native, vec![b'2']);
103     let secret_key =
104         SecretKey::new_without_alias(&calling_info, AuthType::Any, Accessibility::DevicePowerOn, false).unwrap();
105     secret_key.generate().unwrap();
106 
107     let mut crypto = Crypto::build(secret_key.clone(), calling_info, 600).unwrap();
108     crypto.init_key().unwrap();
109     let _ = secret_key.delete();
110 }
111 
112 #[test]
crypto_exec()113 fn crypto_exec() {
114     assert_eq!(0, grant_self_permission());
115     let calling_info = CallingInfo::new(0, OwnerType::Native, vec![b'2']);
116     let secret_key =
117         SecretKey::new_without_alias(&calling_info, AuthType::Any, Accessibility::DevicePowerOn, false).unwrap();
118     secret_key.generate().unwrap();
119 
120     let msg = vec![1, 2, 3, 4, 5, 6];
121     let aad = vec![0; AAD_SIZE as usize];
122     let cipher = Crypto::encrypt(&secret_key, &msg, &aad).unwrap();
123     let mut crypto = Crypto::build(secret_key.clone(), calling_info, 600).unwrap();
124     crypto.init_key().unwrap();
125 
126     let authtoken = vec![0; 280];
127     assert!(crypto.exec_crypt(&cipher, &aad, &authtoken).is_err());
128     let _ = secret_key.delete();
129 }
130 
131 #[test]
crypto_manager()132 fn crypto_manager() {
133     assert_eq!(0, grant_self_permission());
134     let calling_info = CallingInfo::new(0, OwnerType::Native, vec![b'2']);
135     let secret_key1 =
136         SecretKey::new_without_alias(&calling_info, AuthType::Any, Accessibility::DevicePowerOn, false).unwrap();
137     secret_key1.generate().unwrap();
138     let mut crypto1 = Crypto::build(secret_key1.clone(), calling_info.clone(), 600).unwrap();
139     let challenge1 = crypto1.init_key().unwrap().clone();
140 
141     let secret_key2 =
142         SecretKey::new_without_alias(&calling_info, AuthType::Any, Accessibility::DevicePowerOn, false).unwrap();
143     secret_key2.generate().unwrap();
144     let mut crypto2 = Crypto::build(secret_key2.clone(), calling_info.clone(), 600).unwrap();
145     let challenge2 = crypto2.init_key().unwrap().clone();
146 
147     let arc_crypto_manager = CryptoManager::get_instance();
148     let mut crypto_manager = arc_crypto_manager.lock().unwrap();
149     crypto_manager.add(crypto1).unwrap();
150     crypto_manager.add(crypto2).unwrap();
151 
152     let calling_info_2 = CallingInfo::new(0, OwnerType::Native, vec![b'3']);
153     crypto_manager.find(&calling_info, &challenge1).unwrap();
154     crypto_manager.find(&calling_info, &challenge2).unwrap();
155     assert_eq!(ErrCode::NotFound, crypto_manager.find(&calling_info_2, &challenge2).err().unwrap().code);
156 
157     crypto_manager.remove(&calling_info, &challenge1);
158     crypto_manager.remove(&calling_info_2, &challenge2);
159     crypto_manager.find(&calling_info, &challenge2).unwrap();
160     crypto_manager.remove(&calling_info, &challenge2);
161     assert_eq!(ErrCode::NotFound, crypto_manager.find(&calling_info, &challenge2).err().unwrap().code);
162 
163     crypto_manager.remove_need_device_unlocked();
164 
165     let _ = secret_key1.delete();
166     let _ = secret_key2.delete();
167 }
168