xref: /aosp_15_r20/system/security/keystore2/src/super_key/tests.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1 // Copyright 2020, The Android Open Source Project
2 //
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 //! Super-key tests.
16 
17 use super::*;
18 use crate::database::tests::make_bootlevel_key_entry;
19 use crate::database::tests::make_test_key_entry;
20 use crate::database::tests::new_test_db;
21 use rand::prelude::*;
22 const USER_ID: u32 = 0;
23 const TEST_KEY_ALIAS: &str = "TEST_KEY";
24 const TEST_BOOT_KEY_ALIAS: &str = "TEST_BOOT_KEY";
25 
generate_password_blob() -> Password<'static>26 pub fn generate_password_blob() -> Password<'static> {
27     let mut rng = rand::thread_rng();
28     let mut password = vec![0u8; 64];
29     rng.fill_bytes(&mut password);
30 
31     let mut zvec = ZVec::new(64).expect("Failed to create ZVec");
32     zvec[..].copy_from_slice(&password[..]);
33 
34     Password::Owned(zvec)
35 }
36 
setup_test(pw: &Password) -> (Arc<RwLock<SuperKeyManager>>, KeystoreDB, LegacyImporter)37 fn setup_test(pw: &Password) -> (Arc<RwLock<SuperKeyManager>>, KeystoreDB, LegacyImporter) {
38     let mut keystore_db = new_test_db().unwrap();
39     let mut legacy_importer = LegacyImporter::new(Arc::new(Default::default()));
40     legacy_importer.set_empty();
41     let skm: Arc<RwLock<SuperKeyManager>> = Default::default();
42     assert!(skm
43         .write()
44         .unwrap()
45         .initialize_user(&mut keystore_db, &legacy_importer, USER_ID, pw, false)
46         .is_ok());
47     (skm, keystore_db, legacy_importer)
48 }
49 
assert_unlocked( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )50 fn assert_unlocked(
51     skm: &Arc<RwLock<SuperKeyManager>>,
52     keystore_db: &mut KeystoreDB,
53     legacy_importer: &LegacyImporter,
54     user_id: u32,
55     err_msg: &str,
56 ) {
57     let user_state =
58         skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
59     match user_state {
60         UserState::AfterFirstUnlock(_) => {}
61         _ => panic!("{}", err_msg),
62     }
63 }
64 
assert_locked( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )65 fn assert_locked(
66     skm: &Arc<RwLock<SuperKeyManager>>,
67     keystore_db: &mut KeystoreDB,
68     legacy_importer: &LegacyImporter,
69     user_id: u32,
70     err_msg: &str,
71 ) {
72     let user_state =
73         skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
74     match user_state {
75         UserState::BeforeFirstUnlock => {}
76         _ => panic!("{}", err_msg),
77     }
78 }
79 
assert_uninitialized( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )80 fn assert_uninitialized(
81     skm: &Arc<RwLock<SuperKeyManager>>,
82     keystore_db: &mut KeystoreDB,
83     legacy_importer: &LegacyImporter,
84     user_id: u32,
85     err_msg: &str,
86 ) {
87     let user_state =
88         skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
89     match user_state {
90         UserState::Uninitialized => {}
91         _ => panic!("{}", err_msg),
92     }
93 }
94 
95 #[test]
test_initialize_user()96 fn test_initialize_user() {
97     let pw: Password = generate_password_blob();
98     let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
99     assert_unlocked(
100         &skm,
101         &mut keystore_db,
102         &legacy_importer,
103         USER_ID,
104         "The user was not unlocked after initialization!",
105     );
106 }
107 
108 #[test]
test_unlock_user()109 fn test_unlock_user() {
110     let pw: Password = generate_password_blob();
111     let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
112     assert_unlocked(
113         &skm,
114         &mut keystore_db,
115         &legacy_importer,
116         USER_ID,
117         "The user was not unlocked after initialization!",
118     );
119 
120     skm.write().unwrap().data.user_keys.clear();
121     assert_locked(
122         &skm,
123         &mut keystore_db,
124         &legacy_importer,
125         USER_ID,
126         "Clearing the cache did not lock the user!",
127     );
128 
129     assert!(skm
130         .write()
131         .unwrap()
132         .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &pw)
133         .is_ok());
134     assert_unlocked(&skm, &mut keystore_db, &legacy_importer, USER_ID, "The user did not unlock!");
135 }
136 
137 #[test]
test_unlock_wrong_password()138 fn test_unlock_wrong_password() {
139     let pw: Password = generate_password_blob();
140     let wrong_pw: Password = generate_password_blob();
141     let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
142     assert_unlocked(
143         &skm,
144         &mut keystore_db,
145         &legacy_importer,
146         USER_ID,
147         "The user was not unlocked after initialization!",
148     );
149 
150     skm.write().unwrap().data.user_keys.clear();
151     assert_locked(
152         &skm,
153         &mut keystore_db,
154         &legacy_importer,
155         USER_ID,
156         "Clearing the cache did not lock the user!",
157     );
158 
159     assert!(skm
160         .write()
161         .unwrap()
162         .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &wrong_pw)
163         .is_err());
164     assert_locked(
165         &skm,
166         &mut keystore_db,
167         &legacy_importer,
168         USER_ID,
169         "The user was unlocked with an incorrect password!",
170     );
171 }
172 
173 #[test]
test_unlock_user_idempotent()174 fn test_unlock_user_idempotent() {
175     let pw: Password = generate_password_blob();
176     let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
177     assert_unlocked(
178         &skm,
179         &mut keystore_db,
180         &legacy_importer,
181         USER_ID,
182         "The user was not unlocked after initialization!",
183     );
184 
185     skm.write().unwrap().data.user_keys.clear();
186     assert_locked(
187         &skm,
188         &mut keystore_db,
189         &legacy_importer,
190         USER_ID,
191         "Clearing the cache did not lock the user!",
192     );
193 
194     for _ in 0..5 {
195         assert!(skm
196             .write()
197             .unwrap()
198             .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &pw)
199             .is_ok());
200         assert_unlocked(
201             &skm,
202             &mut keystore_db,
203             &legacy_importer,
204             USER_ID,
205             "The user did not unlock!",
206         );
207     }
208 }
209 
test_user_removal(locked: bool)210 fn test_user_removal(locked: bool) {
211     let pw: Password = generate_password_blob();
212     let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
213     assert_unlocked(
214         &skm,
215         &mut keystore_db,
216         &legacy_importer,
217         USER_ID,
218         "The user was not unlocked after initialization!",
219     );
220 
221     assert!(make_test_key_entry(
222         &mut keystore_db,
223         Domain::APP,
224         USER_ID.into(),
225         TEST_KEY_ALIAS,
226         None
227     )
228     .is_ok());
229     assert!(make_bootlevel_key_entry(
230         &mut keystore_db,
231         Domain::APP,
232         USER_ID.into(),
233         TEST_BOOT_KEY_ALIAS,
234         false
235     )
236     .is_ok());
237 
238     assert!(keystore_db
239         .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
240         .unwrap());
241     assert!(keystore_db
242         .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
243         .unwrap());
244 
245     if locked {
246         skm.write().unwrap().data.user_keys.clear();
247         assert_locked(
248             &skm,
249             &mut keystore_db,
250             &legacy_importer,
251             USER_ID,
252             "Clearing the cache did not lock the user!",
253         );
254     }
255 
256     assert!(skm.write().unwrap().remove_user(&mut keystore_db, &legacy_importer, USER_ID).is_ok());
257     assert_uninitialized(
258         &skm,
259         &mut keystore_db,
260         &legacy_importer,
261         USER_ID,
262         "The user was not removed!",
263     );
264 
265     assert!(!skm
266         .write()
267         .unwrap()
268         .super_key_exists_in_db_for_user(&mut keystore_db, &legacy_importer, USER_ID)
269         .unwrap());
270 
271     assert!(!keystore_db
272         .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
273         .unwrap());
274     assert!(!keystore_db
275         .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
276         .unwrap());
277 }
278 
279 #[test]
test_remove_unlocked_user()280 fn test_remove_unlocked_user() {
281     test_user_removal(false);
282 }
283 
284 #[test]
test_remove_locked_user()285 fn test_remove_locked_user() {
286     test_user_removal(true);
287 }
288