xref: /aosp_15_r20/system/security/keystore2/src/database/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 //! Database tests.
16 
17 use super::*;
18 use crate::key_parameter::{
19     Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyOrigin, KeyParameter,
20     KeyParameterValue, KeyPurpose, PaddingMode, SecurityLevel,
21 };
22 use crate::key_perm_set;
23 use crate::permission::{KeyPerm, KeyPermSet};
24 use crate::super_key::{SuperKeyManager, USER_AFTER_FIRST_UNLOCK_SUPER_KEY, SuperEncryptionAlgorithm, SuperKeyType};
25 use keystore2_test_utils::TempDir;
26 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
27     HardwareAuthToken::HardwareAuthToken,
28     HardwareAuthenticatorType::HardwareAuthenticatorType as kmhw_authenticator_type,
29 };
30 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
31     Timestamp::Timestamp,
32 };
33 use std::cell::RefCell;
34 use std::collections::BTreeMap;
35 use std::fmt::Write;
36 use std::sync::atomic::{AtomicU8, Ordering};
37 use std::sync::Arc;
38 use std::thread;
39 use std::time::{Duration, SystemTime};
40 use crate::utils::AesGcm;
41 #[cfg(disabled)]
42 use std::time::Instant;
43 
new_test_db() -> Result<KeystoreDB>44 pub fn new_test_db() -> Result<KeystoreDB> {
45     new_test_db_at("file::memory:")
46 }
47 
new_test_db_at(path: &str) -> Result<KeystoreDB>48 fn new_test_db_at(path: &str) -> Result<KeystoreDB> {
49     let conn = KeystoreDB::make_connection(path)?;
50 
51     let mut db = KeystoreDB { conn, gc: None, perboot: Arc::new(perboot::PerbootDB::new()) };
52     db.with_transaction(Immediate("TX_new_test_db"), |tx| {
53         KeystoreDB::init_tables(tx).context("Failed to initialize tables.").no_gc()
54     })?;
55     Ok(db)
56 }
57 
rebind_alias( db: &mut KeystoreDB, newid: &KeyIdGuard, alias: &str, domain: Domain, namespace: i64, ) -> Result<bool>58 fn rebind_alias(
59     db: &mut KeystoreDB,
60     newid: &KeyIdGuard,
61     alias: &str,
62     domain: Domain,
63     namespace: i64,
64 ) -> Result<bool> {
65     db.with_transaction(Immediate("TX_rebind_alias"), |tx| {
66         KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace, KeyType::Client).no_gc()
67     })
68     .context(ks_err!())
69 }
70 
71 #[test]
datetime() -> Result<()>72 fn datetime() -> Result<()> {
73     let conn = Connection::open_in_memory()?;
74     conn.execute("CREATE TABLE test (ts DATETIME);", [])?;
75     let now = SystemTime::now();
76     let duration = Duration::from_secs(1000);
77     let then = now.checked_sub(duration).unwrap();
78     let soon = now.checked_add(duration).unwrap();
79     conn.execute(
80         "INSERT INTO test (ts) VALUES (?), (?), (?);",
81         params![DateTime::try_from(now)?, DateTime::try_from(then)?, DateTime::try_from(soon)?],
82     )?;
83     let mut stmt = conn.prepare("SELECT ts FROM test ORDER BY ts ASC;")?;
84     let mut rows = stmt.query([])?;
85     assert_eq!(DateTime::try_from(then)?, rows.next()?.unwrap().get(0)?);
86     assert_eq!(DateTime::try_from(now)?, rows.next()?.unwrap().get(0)?);
87     assert_eq!(DateTime::try_from(soon)?, rows.next()?.unwrap().get(0)?);
88     assert!(rows.next()?.is_none());
89     assert!(DateTime::try_from(then)? < DateTime::try_from(now)?);
90     assert!(DateTime::try_from(then)? < DateTime::try_from(soon)?);
91     assert!(DateTime::try_from(now)? < DateTime::try_from(soon)?);
92     Ok(())
93 }
94 
95 // Ensure that we're using the "injected" random function, not the real one.
96 #[test]
test_mocked_random()97 fn test_mocked_random() {
98     let rand1 = random();
99     let rand2 = random();
100     let rand3 = random();
101     if rand1 == rand2 {
102         assert_eq!(rand2 + 1, rand3);
103     } else {
104         assert_eq!(rand1 + 1, rand2);
105         assert_eq!(rand2, rand3);
106     }
107 }
108 
109 // Test that we have the correct tables.
110 #[test]
test_tables() -> Result<()>111 fn test_tables() -> Result<()> {
112     let db = new_test_db()?;
113     let tables = db
114         .conn
115         .prepare("SELECT name from persistent.sqlite_master WHERE type='table' ORDER BY name;")?
116         .query_map(params![], |row| row.get(0))?
117         .collect::<rusqlite::Result<Vec<String>>>()?;
118     assert_eq!(tables.len(), 6);
119     assert_eq!(tables[0], "blobentry");
120     assert_eq!(tables[1], "blobmetadata");
121     assert_eq!(tables[2], "grant");
122     assert_eq!(tables[3], "keyentry");
123     assert_eq!(tables[4], "keymetadata");
124     assert_eq!(tables[5], "keyparameter");
125     Ok(())
126 }
127 
128 #[test]
test_auth_token_table_invariant() -> Result<()>129 fn test_auth_token_table_invariant() -> Result<()> {
130     let mut db = new_test_db()?;
131     let auth_token1 = HardwareAuthToken {
132         challenge: i64::MAX,
133         userId: 200,
134         authenticatorId: 200,
135         authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
136         timestamp: Timestamp { milliSeconds: 500 },
137         mac: String::from("mac").into_bytes(),
138     };
139     db.insert_auth_token(&auth_token1);
140     let auth_tokens_returned = get_auth_tokens(&db);
141     assert_eq!(auth_tokens_returned.len(), 1);
142 
143     // insert another auth token with the same values for the columns in the UNIQUE constraint
144     // of the auth token table and different value for timestamp
145     let auth_token2 = HardwareAuthToken {
146         challenge: i64::MAX,
147         userId: 200,
148         authenticatorId: 200,
149         authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
150         timestamp: Timestamp { milliSeconds: 600 },
151         mac: String::from("mac").into_bytes(),
152     };
153 
154     db.insert_auth_token(&auth_token2);
155     let mut auth_tokens_returned = get_auth_tokens(&db);
156     assert_eq!(auth_tokens_returned.len(), 1);
157 
158     if let Some(auth_token) = auth_tokens_returned.pop() {
159         assert_eq!(auth_token.auth_token.timestamp.milliSeconds, 600);
160     }
161 
162     // insert another auth token with the different values for the columns in the UNIQUE
163     // constraint of the auth token table
164     let auth_token3 = HardwareAuthToken {
165         challenge: i64::MAX,
166         userId: 201,
167         authenticatorId: 200,
168         authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
169         timestamp: Timestamp { milliSeconds: 600 },
170         mac: String::from("mac").into_bytes(),
171     };
172 
173     db.insert_auth_token(&auth_token3);
174     let auth_tokens_returned = get_auth_tokens(&db);
175     assert_eq!(auth_tokens_returned.len(), 2);
176 
177     Ok(())
178 }
179 
180 // utility function for test_auth_token_table_invariant()
get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry>181 fn get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry> {
182     db.perboot.get_all_auth_token_entries()
183 }
184 
create_key_entry( db: &mut KeystoreDB, domain: &Domain, namespace: &i64, key_type: KeyType, km_uuid: &Uuid, ) -> Result<KeyIdGuard>185 fn create_key_entry(
186     db: &mut KeystoreDB,
187     domain: &Domain,
188     namespace: &i64,
189     key_type: KeyType,
190     km_uuid: &Uuid,
191 ) -> Result<KeyIdGuard> {
192     db.with_transaction(Immediate("TX_create_key_entry"), |tx| {
193         KeystoreDB::create_key_entry_internal(tx, domain, namespace, key_type, km_uuid).no_gc()
194     })
195 }
196 
197 #[test]
test_persistence_for_files() -> Result<()>198 fn test_persistence_for_files() -> Result<()> {
199     let temp_dir = TempDir::new("persistent_db_test")?;
200     let mut db = KeystoreDB::new(temp_dir.path(), None)?;
201 
202     create_key_entry(&mut db, &Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
203     let entries = get_keyentry(&db)?;
204     assert_eq!(entries.len(), 1);
205 
206     let db = KeystoreDB::new(temp_dir.path(), None)?;
207 
208     let entries_new = get_keyentry(&db)?;
209     assert_eq!(entries, entries_new);
210     Ok(())
211 }
212 
213 #[test]
test_create_key_entry() -> Result<()>214 fn test_create_key_entry() -> Result<()> {
215     fn extractor(ke: &KeyEntryRow) -> (Domain, i64, Option<&str>, Uuid) {
216         (ke.domain.unwrap(), ke.namespace.unwrap(), ke.alias.as_deref(), ke.km_uuid.unwrap())
217     }
218 
219     let mut db = new_test_db()?;
220 
221     create_key_entry(&mut db, &Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
222     create_key_entry(&mut db, &Domain::SELINUX, &101, KeyType::Client, &KEYSTORE_UUID)?;
223 
224     let entries = get_keyentry(&db)?;
225     assert_eq!(entries.len(), 2);
226     assert_eq!(extractor(&entries[0]), (Domain::APP, 100, None, KEYSTORE_UUID));
227     assert_eq!(extractor(&entries[1]), (Domain::SELINUX, 101, None, KEYSTORE_UUID));
228 
229     // Test that we must pass in a valid Domain.
230     check_result_is_error_containing_string(
231         create_key_entry(&mut db, &Domain::GRANT, &102, KeyType::Client, &KEYSTORE_UUID),
232         &format!("Domain {:?} must be either App or SELinux.", Domain::GRANT),
233     );
234     check_result_is_error_containing_string(
235         create_key_entry(&mut db, &Domain::BLOB, &103, KeyType::Client, &KEYSTORE_UUID),
236         &format!("Domain {:?} must be either App or SELinux.", Domain::BLOB),
237     );
238     check_result_is_error_containing_string(
239         create_key_entry(&mut db, &Domain::KEY_ID, &104, KeyType::Client, &KEYSTORE_UUID),
240         &format!("Domain {:?} must be either App or SELinux.", Domain::KEY_ID),
241     );
242 
243     Ok(())
244 }
245 
246 #[test]
test_rebind_alias() -> Result<()>247 fn test_rebind_alias() -> Result<()> {
248     fn extractor(ke: &KeyEntryRow) -> (Option<Domain>, Option<i64>, Option<&str>, Option<Uuid>) {
249         (ke.domain, ke.namespace, ke.alias.as_deref(), ke.km_uuid)
250     }
251 
252     let mut db = new_test_db()?;
253     create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
254     create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
255     let entries = get_keyentry(&db)?;
256     assert_eq!(entries.len(), 2);
257     assert_eq!(extractor(&entries[0]), (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID)));
258     assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID)));
259 
260     // Test that the first call to rebind_alias sets the alias.
261     rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[0].id), "foo", Domain::APP, 42)?;
262     let entries = get_keyentry(&db)?;
263     assert_eq!(entries.len(), 2);
264     assert_eq!(
265         extractor(&entries[0]),
266         (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
267     );
268     assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID)));
269 
270     // Test that the second call to rebind_alias also empties the old one.
271     rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[1].id), "foo", Domain::APP, 42)?;
272     let entries = get_keyentry(&db)?;
273     assert_eq!(entries.len(), 2);
274     assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
275     assert_eq!(
276         extractor(&entries[1]),
277         (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
278     );
279 
280     // Test that we must pass in a valid Domain.
281     check_result_is_error_containing_string(
282         rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::GRANT, 42),
283         &format!("Domain {:?} must be either App or SELinux.", Domain::GRANT),
284     );
285     check_result_is_error_containing_string(
286         rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::BLOB, 42),
287         &format!("Domain {:?} must be either App or SELinux.", Domain::BLOB),
288     );
289     check_result_is_error_containing_string(
290         rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::KEY_ID, 42),
291         &format!("Domain {:?} must be either App or SELinux.", Domain::KEY_ID),
292     );
293 
294     // Test that we correctly handle setting an alias for something that does not exist.
295     check_result_is_error_containing_string(
296         rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::SELINUX, 42),
297         "Expected to update a single entry but instead updated 0",
298     );
299     // Test that we correctly abort the transaction in this case.
300     let entries = get_keyentry(&db)?;
301     assert_eq!(entries.len(), 2);
302     assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
303     assert_eq!(
304         extractor(&entries[1]),
305         (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
306     );
307 
308     Ok(())
309 }
310 
311 #[test]
test_grant_ungrant() -> Result<()>312 fn test_grant_ungrant() -> Result<()> {
313     const CALLER_UID: u32 = 15;
314     const GRANTEE_UID: u32 = 12;
315     const SELINUX_NAMESPACE: i64 = 7;
316 
317     let mut db = new_test_db()?;
318     db.conn.execute(
319         "INSERT INTO persistent.keyentry (id, key_type, domain, namespace, alias, state, km_uuid)
320                 VALUES (1, 0, 0, 15, 'key', 1, ?), (2, 0, 2, 7, 'yek', 1, ?);",
321         params![KEYSTORE_UUID, KEYSTORE_UUID],
322     )?;
323     let app_key = KeyDescriptor {
324         domain: super::Domain::APP,
325         nspace: 0,
326         alias: Some("key".to_string()),
327         blob: None,
328     };
329     const PVEC1: KeyPermSet = key_perm_set![KeyPerm::Use, KeyPerm::GetInfo];
330     const PVEC2: KeyPermSet = key_perm_set![KeyPerm::Use];
331 
332     // Reset totally predictable random number generator in case we
333     // are not the first test running on this thread.
334     reset_random();
335     let next_random = 0i64;
336 
337     let app_granted_key = db
338         .grant(&app_key, CALLER_UID, GRANTEE_UID, PVEC1, |k, a| {
339             assert_eq!(*a, PVEC1);
340             assert_eq!(
341                 *k,
342                 KeyDescriptor {
343                     domain: super::Domain::APP,
344                     // namespace must be set to the caller_uid.
345                     nspace: CALLER_UID as i64,
346                     alias: Some("key".to_string()),
347                     blob: None,
348                 }
349             );
350             Ok(())
351         })
352         .unwrap();
353 
354     assert_eq!(
355         app_granted_key,
356         KeyDescriptor {
357             domain: super::Domain::GRANT,
358             // The grantid is next_random due to the mock random number generator.
359             nspace: next_random,
360             alias: None,
361             blob: None,
362         }
363     );
364 
365     let selinux_key = KeyDescriptor {
366         domain: super::Domain::SELINUX,
367         nspace: SELINUX_NAMESPACE,
368         alias: Some("yek".to_string()),
369         blob: None,
370     };
371 
372     let selinux_granted_key = db
373         .grant(&selinux_key, CALLER_UID, 12, PVEC1, |k, a| {
374             assert_eq!(*a, PVEC1);
375             assert_eq!(
376                 *k,
377                 KeyDescriptor {
378                     domain: super::Domain::SELINUX,
379                     // namespace must be the supplied SELinux
380                     // namespace.
381                     nspace: SELINUX_NAMESPACE,
382                     alias: Some("yek".to_string()),
383                     blob: None,
384                 }
385             );
386             Ok(())
387         })
388         .unwrap();
389 
390     assert_eq!(
391         selinux_granted_key,
392         KeyDescriptor {
393             domain: super::Domain::GRANT,
394             // The grantid is next_random + 1 due to the mock random number generator.
395             nspace: next_random + 1,
396             alias: None,
397             blob: None,
398         }
399     );
400 
401     // This should update the existing grant with PVEC2.
402     let selinux_granted_key = db
403         .grant(&selinux_key, CALLER_UID, 12, PVEC2, |k, a| {
404             assert_eq!(*a, PVEC2);
405             assert_eq!(
406                 *k,
407                 KeyDescriptor {
408                     domain: super::Domain::SELINUX,
409                     // namespace must be the supplied SELinux
410                     // namespace.
411                     nspace: SELINUX_NAMESPACE,
412                     alias: Some("yek".to_string()),
413                     blob: None,
414                 }
415             );
416             Ok(())
417         })
418         .unwrap();
419 
420     assert_eq!(
421         selinux_granted_key,
422         KeyDescriptor {
423             domain: super::Domain::GRANT,
424             // Same grant id as before. The entry was only updated.
425             nspace: next_random + 1,
426             alias: None,
427             blob: None,
428         }
429     );
430 
431     {
432         // Limiting scope of stmt, because it borrows db.
433         let mut stmt = db
434             .conn
435             .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
436         let mut rows = stmt.query_map::<(i64, u32, i64, KeyPermSet), _, _>([], |row| {
437             Ok((row.get(0)?, row.get(1)?, row.get(2)?, KeyPermSet::from(row.get::<_, i32>(3)?)))
438         })?;
439 
440         let r = rows.next().unwrap().unwrap();
441         assert_eq!(r, (next_random, GRANTEE_UID, 1, PVEC1));
442         let r = rows.next().unwrap().unwrap();
443         assert_eq!(r, (next_random + 1, GRANTEE_UID, 2, PVEC2));
444         assert!(rows.next().is_none());
445     }
446 
447     debug_dump_keyentry_table(&mut db)?;
448     println!("app_key {:?}", app_key);
449     println!("selinux_key {:?}", selinux_key);
450 
451     db.ungrant(&app_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
452     db.ungrant(&selinux_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
453 
454     Ok(())
455 }
456 
457 static TEST_KEY_BLOB: &[u8] = b"my test blob";
458 static TEST_CERT_BLOB: &[u8] = b"my test cert";
459 static TEST_CERT_CHAIN_BLOB: &[u8] = b"my test cert_chain";
460 
461 #[test]
test_set_blob() -> Result<()>462 fn test_set_blob() -> Result<()> {
463     let key_id = KEY_ID_LOCK.get(3000);
464     let mut db = new_test_db()?;
465     let mut blob_metadata = BlobMetaData::new();
466     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
467     db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), Some(&blob_metadata))?;
468     db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
469     db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
470     drop(key_id);
471 
472     let mut stmt = db.conn.prepare(
473         "SELECT subcomponent_type, keyentryid, blob, id FROM persistent.blobentry
474                 ORDER BY subcomponent_type ASC;",
475     )?;
476     let mut rows = stmt.query_map::<((SubComponentType, i64, Vec<u8>), i64), _, _>([], |row| {
477         Ok(((row.get(0)?, row.get(1)?, row.get(2)?), row.get(3)?))
478     })?;
479     let (r, id) = rows.next().unwrap().unwrap();
480     assert_eq!(r, (SubComponentType::KEY_BLOB, 3000, TEST_KEY_BLOB.to_vec()));
481     let (r, _) = rows.next().unwrap().unwrap();
482     assert_eq!(r, (SubComponentType::CERT, 3000, TEST_CERT_BLOB.to_vec()));
483     let (r, _) = rows.next().unwrap().unwrap();
484     assert_eq!(r, (SubComponentType::CERT_CHAIN, 3000, TEST_CERT_CHAIN_BLOB.to_vec()));
485 
486     drop(rows);
487     drop(stmt);
488 
489     assert_eq!(
490         db.with_transaction(Immediate("TX_test"), |tx| {
491             BlobMetaData::load_from_db(id, tx).no_gc()
492         })
493         .expect("Should find blob metadata."),
494         blob_metadata
495     );
496     Ok(())
497 }
498 
499 static TEST_ALIAS: &str = "my super duper key";
500 
501 #[test]
test_insert_and_load_full_keyentry_domain_app() -> Result<()>502 fn test_insert_and_load_full_keyentry_domain_app() -> Result<()> {
503     let mut db = new_test_db()?;
504     let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
505         .context("test_insert_and_load_full_keyentry_domain_app")?
506         .0;
507     let (_key_guard, key_entry) = db
508         .load_key_entry(
509             &KeyDescriptor {
510                 domain: Domain::APP,
511                 nspace: 0,
512                 alias: Some(TEST_ALIAS.to_string()),
513                 blob: None,
514             },
515             KeyType::Client,
516             KeyEntryLoadBits::BOTH,
517             1,
518             |_k, _av| Ok(()),
519         )
520         .unwrap();
521     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
522 
523     db.unbind_key(
524         &KeyDescriptor {
525             domain: Domain::APP,
526             nspace: 0,
527             alias: Some(TEST_ALIAS.to_string()),
528             blob: None,
529         },
530         KeyType::Client,
531         1,
532         |_, _| Ok(()),
533     )
534     .unwrap();
535 
536     assert_eq!(
537         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
538         db.load_key_entry(
539             &KeyDescriptor {
540                 domain: Domain::APP,
541                 nspace: 0,
542                 alias: Some(TEST_ALIAS.to_string()),
543                 blob: None,
544             },
545             KeyType::Client,
546             KeyEntryLoadBits::NONE,
547             1,
548             |_k, _av| Ok(()),
549         )
550         .unwrap_err()
551         .root_cause()
552         .downcast_ref::<KsError>()
553     );
554 
555     Ok(())
556 }
557 
558 #[test]
test_insert_and_load_certificate_entry_domain_app() -> Result<()>559 fn test_insert_and_load_certificate_entry_domain_app() -> Result<()> {
560     let mut db = new_test_db()?;
561 
562     db.store_new_certificate(
563         &KeyDescriptor {
564             domain: Domain::APP,
565             nspace: 1,
566             alias: Some(TEST_ALIAS.to_string()),
567             blob: None,
568         },
569         KeyType::Client,
570         TEST_CERT_BLOB,
571         &KEYSTORE_UUID,
572     )
573     .expect("Trying to insert cert.");
574 
575     let (_key_guard, mut key_entry) = db
576         .load_key_entry(
577             &KeyDescriptor {
578                 domain: Domain::APP,
579                 nspace: 1,
580                 alias: Some(TEST_ALIAS.to_string()),
581                 blob: None,
582             },
583             KeyType::Client,
584             KeyEntryLoadBits::PUBLIC,
585             1,
586             |_k, _av| Ok(()),
587         )
588         .expect("Trying to read certificate entry.");
589 
590     assert!(key_entry.pure_cert());
591     assert!(key_entry.cert().is_none());
592     assert_eq!(key_entry.take_cert_chain(), Some(TEST_CERT_BLOB.to_vec()));
593 
594     db.unbind_key(
595         &KeyDescriptor {
596             domain: Domain::APP,
597             nspace: 1,
598             alias: Some(TEST_ALIAS.to_string()),
599             blob: None,
600         },
601         KeyType::Client,
602         1,
603         |_, _| Ok(()),
604     )
605     .unwrap();
606 
607     assert_eq!(
608         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
609         db.load_key_entry(
610             &KeyDescriptor {
611                 domain: Domain::APP,
612                 nspace: 1,
613                 alias: Some(TEST_ALIAS.to_string()),
614                 blob: None,
615             },
616             KeyType::Client,
617             KeyEntryLoadBits::NONE,
618             1,
619             |_k, _av| Ok(()),
620         )
621         .unwrap_err()
622         .root_cause()
623         .downcast_ref::<KsError>()
624     );
625 
626     Ok(())
627 }
628 
629 #[test]
test_insert_and_load_full_keyentry_domain_selinux() -> Result<()>630 fn test_insert_and_load_full_keyentry_domain_selinux() -> Result<()> {
631     let mut db = new_test_db()?;
632     let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
633         .context("test_insert_and_load_full_keyentry_domain_selinux")?
634         .0;
635     let (_key_guard, key_entry) = db
636         .load_key_entry(
637             &KeyDescriptor {
638                 domain: Domain::SELINUX,
639                 nspace: 1,
640                 alias: Some(TEST_ALIAS.to_string()),
641                 blob: None,
642             },
643             KeyType::Client,
644             KeyEntryLoadBits::BOTH,
645             1,
646             |_k, _av| Ok(()),
647         )
648         .unwrap();
649     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
650 
651     db.unbind_key(
652         &KeyDescriptor {
653             domain: Domain::SELINUX,
654             nspace: 1,
655             alias: Some(TEST_ALIAS.to_string()),
656             blob: None,
657         },
658         KeyType::Client,
659         1,
660         |_, _| Ok(()),
661     )
662     .unwrap();
663 
664     assert_eq!(
665         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
666         db.load_key_entry(
667             &KeyDescriptor {
668                 domain: Domain::SELINUX,
669                 nspace: 1,
670                 alias: Some(TEST_ALIAS.to_string()),
671                 blob: None,
672             },
673             KeyType::Client,
674             KeyEntryLoadBits::NONE,
675             1,
676             |_k, _av| Ok(()),
677         )
678         .unwrap_err()
679         .root_cause()
680         .downcast_ref::<KsError>()
681     );
682 
683     Ok(())
684 }
685 
686 #[test]
test_insert_and_load_full_keyentry_domain_key_id() -> Result<()>687 fn test_insert_and_load_full_keyentry_domain_key_id() -> Result<()> {
688     let mut db = new_test_db()?;
689     let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
690         .context("test_insert_and_load_full_keyentry_domain_key_id")?
691         .0;
692     let (_, key_entry) = db
693         .load_key_entry(
694             &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
695             KeyType::Client,
696             KeyEntryLoadBits::BOTH,
697             1,
698             |_k, _av| Ok(()),
699         )
700         .unwrap();
701 
702     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
703 
704     db.unbind_key(
705         &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
706         KeyType::Client,
707         1,
708         |_, _| Ok(()),
709     )
710     .unwrap();
711 
712     assert_eq!(
713         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
714         db.load_key_entry(
715             &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
716             KeyType::Client,
717             KeyEntryLoadBits::NONE,
718             1,
719             |_k, _av| Ok(()),
720         )
721         .unwrap_err()
722         .root_cause()
723         .downcast_ref::<KsError>()
724     );
725 
726     Ok(())
727 }
728 
729 #[test]
test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()>730 fn test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()> {
731     let mut db = new_test_db()?;
732     let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(123))
733         .context("test_check_and_update_key_usage_count_with_limited_use_key")?
734         .0;
735     // Update the usage count of the limited use key.
736     db.check_and_update_key_usage_count(key_id)?;
737 
738     let (_key_guard, key_entry) = db.load_key_entry(
739         &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
740         KeyType::Client,
741         KeyEntryLoadBits::BOTH,
742         1,
743         |_k, _av| Ok(()),
744     )?;
745 
746     // The usage count is decremented now.
747     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, Some(122)));
748 
749     Ok(())
750 }
751 
752 #[test]
test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()>753 fn test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()> {
754     let mut db = new_test_db()?;
755     let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(1))
756         .context("test_check_and_update_key_usage_count_with_exhausted_limited_use_key")?
757         .0;
758     // Update the usage count of the limited use key.
759     db.check_and_update_key_usage_count(key_id).expect(concat!(
760         "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
761         "This should succeed."
762     ));
763 
764     // Try to update the exhausted limited use key.
765     let e = db.check_and_update_key_usage_count(key_id).expect_err(concat!(
766         "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
767         "This should fail."
768     ));
769     assert_eq!(
770         &KsError::Km(ErrorCode::INVALID_KEY_BLOB),
771         e.root_cause().downcast_ref::<KsError>().unwrap()
772     );
773 
774     Ok(())
775 }
776 
777 #[test]
test_insert_and_load_full_keyentry_from_grant() -> Result<()>778 fn test_insert_and_load_full_keyentry_from_grant() -> Result<()> {
779     let mut db = new_test_db()?;
780     let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
781         .context("test_insert_and_load_full_keyentry_from_grant")?
782         .0;
783 
784     let granted_key = db
785         .grant(
786             &KeyDescriptor {
787                 domain: Domain::APP,
788                 nspace: 0,
789                 alias: Some(TEST_ALIAS.to_string()),
790                 blob: None,
791             },
792             1,
793             2,
794             key_perm_set![KeyPerm::Use],
795             |_k, _av| Ok(()),
796         )
797         .unwrap();
798 
799     debug_dump_grant_table(&mut db)?;
800 
801     let (_key_guard, key_entry) = db
802         .load_key_entry(&granted_key, KeyType::Client, KeyEntryLoadBits::BOTH, 2, |k, av| {
803             assert_eq!(Domain::GRANT, k.domain);
804             assert!(av.unwrap().includes(KeyPerm::Use));
805             Ok(())
806         })
807         .unwrap();
808 
809     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
810 
811     db.unbind_key(&granted_key, KeyType::Client, 2, |_, _| Ok(())).unwrap();
812 
813     assert_eq!(
814         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
815         db.load_key_entry(&granted_key, KeyType::Client, KeyEntryLoadBits::NONE, 2, |_k, _av| Ok(
816             ()
817         ),)
818             .unwrap_err()
819             .root_cause()
820             .downcast_ref::<KsError>()
821     );
822 
823     Ok(())
824 }
825 
826 // This test attempts to load a key by key id while the caller is not the owner
827 // but a grant exists for the given key and the caller.
828 #[test]
test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()>829 fn test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()> {
830     let mut db = new_test_db()?;
831     const OWNER_UID: u32 = 1u32;
832     const GRANTEE_UID: u32 = 2u32;
833     const SOMEONE_ELSE_UID: u32 = 3u32;
834     let key_id = make_test_key_entry(&mut db, Domain::APP, OWNER_UID as i64, TEST_ALIAS, None)
835         .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?
836         .0;
837 
838     db.grant(
839         &KeyDescriptor {
840             domain: Domain::APP,
841             nspace: 0,
842             alias: Some(TEST_ALIAS.to_string()),
843             blob: None,
844         },
845         OWNER_UID,
846         GRANTEE_UID,
847         key_perm_set![KeyPerm::Use],
848         |_k, _av| Ok(()),
849     )
850     .unwrap();
851 
852     debug_dump_grant_table(&mut db)?;
853 
854     let id_descriptor =
855         KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, ..Default::default() };
856 
857     let (_, key_entry) = db
858         .load_key_entry(
859             &id_descriptor,
860             KeyType::Client,
861             KeyEntryLoadBits::BOTH,
862             GRANTEE_UID,
863             |k, av| {
864                 assert_eq!(Domain::APP, k.domain);
865                 assert_eq!(OWNER_UID as i64, k.nspace);
866                 assert!(av.unwrap().includes(KeyPerm::Use));
867                 Ok(())
868             },
869         )
870         .unwrap();
871 
872     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
873 
874     let (_, key_entry) = db
875         .load_key_entry(
876             &id_descriptor,
877             KeyType::Client,
878             KeyEntryLoadBits::BOTH,
879             SOMEONE_ELSE_UID,
880             |k, av| {
881                 assert_eq!(Domain::APP, k.domain);
882                 assert_eq!(OWNER_UID as i64, k.nspace);
883                 assert!(av.is_none());
884                 Ok(())
885             },
886         )
887         .unwrap();
888 
889     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
890 
891     db.unbind_key(&id_descriptor, KeyType::Client, OWNER_UID, |_, _| Ok(())).unwrap();
892 
893     assert_eq!(
894         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
895         db.load_key_entry(
896             &id_descriptor,
897             KeyType::Client,
898             KeyEntryLoadBits::NONE,
899             GRANTEE_UID,
900             |_k, _av| Ok(()),
901         )
902         .unwrap_err()
903         .root_cause()
904         .downcast_ref::<KsError>()
905     );
906 
907     Ok(())
908 }
909 
910 // Creates a key migrates it to a different location and then tries to access it by the old
911 // and new location.
912 #[test]
test_migrate_key_app_to_app() -> Result<()>913 fn test_migrate_key_app_to_app() -> Result<()> {
914     let mut db = new_test_db()?;
915     const SOURCE_UID: u32 = 1u32;
916     const DESTINATION_UID: u32 = 2u32;
917     static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
918     static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
919     let key_id_guard =
920         make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
921             .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
922 
923     let source_descriptor: KeyDescriptor = KeyDescriptor {
924         domain: Domain::APP,
925         nspace: -1,
926         alias: Some(SOURCE_ALIAS.to_string()),
927         blob: None,
928     };
929 
930     let destination_descriptor: KeyDescriptor = KeyDescriptor {
931         domain: Domain::APP,
932         nspace: -1,
933         alias: Some(DESTINATION_ALIAS.to_string()),
934         blob: None,
935     };
936 
937     let key_id = key_id_guard.id();
938 
939     db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| Ok(()))
940         .unwrap();
941 
942     let (_, key_entry) = db
943         .load_key_entry(
944             &destination_descriptor,
945             KeyType::Client,
946             KeyEntryLoadBits::BOTH,
947             DESTINATION_UID,
948             |k, av| {
949                 assert_eq!(Domain::APP, k.domain);
950                 assert_eq!(DESTINATION_UID as i64, k.nspace);
951                 assert!(av.is_none());
952                 Ok(())
953             },
954         )
955         .unwrap();
956 
957     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
958 
959     assert_eq!(
960         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
961         db.load_key_entry(
962             &source_descriptor,
963             KeyType::Client,
964             KeyEntryLoadBits::NONE,
965             SOURCE_UID,
966             |_k, _av| Ok(()),
967         )
968         .unwrap_err()
969         .root_cause()
970         .downcast_ref::<KsError>()
971     );
972 
973     Ok(())
974 }
975 
976 // Creates a key migrates it to a different location and then tries to access it by the old
977 // and new location.
978 #[test]
test_migrate_key_app_to_selinux() -> Result<()>979 fn test_migrate_key_app_to_selinux() -> Result<()> {
980     let mut db = new_test_db()?;
981     const SOURCE_UID: u32 = 1u32;
982     const DESTINATION_UID: u32 = 2u32;
983     const DESTINATION_NAMESPACE: i64 = 1000i64;
984     static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
985     static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
986     let key_id_guard =
987         make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
988             .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
989 
990     let source_descriptor: KeyDescriptor = KeyDescriptor {
991         domain: Domain::APP,
992         nspace: -1,
993         alias: Some(SOURCE_ALIAS.to_string()),
994         blob: None,
995     };
996 
997     let destination_descriptor: KeyDescriptor = KeyDescriptor {
998         domain: Domain::SELINUX,
999         nspace: DESTINATION_NAMESPACE,
1000         alias: Some(DESTINATION_ALIAS.to_string()),
1001         blob: None,
1002     };
1003 
1004     let key_id = key_id_guard.id();
1005 
1006     db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| Ok(()))
1007         .unwrap();
1008 
1009     let (_, key_entry) = db
1010         .load_key_entry(
1011             &destination_descriptor,
1012             KeyType::Client,
1013             KeyEntryLoadBits::BOTH,
1014             DESTINATION_UID,
1015             |k, av| {
1016                 assert_eq!(Domain::SELINUX, k.domain);
1017                 assert_eq!(DESTINATION_NAMESPACE, k.nspace);
1018                 assert!(av.is_none());
1019                 Ok(())
1020             },
1021         )
1022         .unwrap();
1023 
1024     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
1025 
1026     assert_eq!(
1027         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
1028         db.load_key_entry(
1029             &source_descriptor,
1030             KeyType::Client,
1031             KeyEntryLoadBits::NONE,
1032             SOURCE_UID,
1033             |_k, _av| Ok(()),
1034         )
1035         .unwrap_err()
1036         .root_cause()
1037         .downcast_ref::<KsError>()
1038     );
1039 
1040     Ok(())
1041 }
1042 
1043 // Creates two keys and tries to migrate the first to the location of the second which
1044 // is expected to fail.
1045 #[test]
test_migrate_key_destination_occupied() -> Result<()>1046 fn test_migrate_key_destination_occupied() -> Result<()> {
1047     let mut db = new_test_db()?;
1048     const SOURCE_UID: u32 = 1u32;
1049     const DESTINATION_UID: u32 = 2u32;
1050     static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
1051     static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
1052     let key_id_guard =
1053         make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
1054             .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
1055     make_test_key_entry(&mut db, Domain::APP, DESTINATION_UID as i64, DESTINATION_ALIAS, None)
1056         .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
1057 
1058     let destination_descriptor: KeyDescriptor = KeyDescriptor {
1059         domain: Domain::APP,
1060         nspace: -1,
1061         alias: Some(DESTINATION_ALIAS.to_string()),
1062         blob: None,
1063     };
1064 
1065     assert_eq!(
1066         Some(&KsError::Rc(ResponseCode::INVALID_ARGUMENT)),
1067         db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| Ok(
1068             ()
1069         ))
1070         .unwrap_err()
1071         .root_cause()
1072         .downcast_ref::<KsError>()
1073     );
1074 
1075     Ok(())
1076 }
1077 
1078 #[test]
test_upgrade_0_to_1()1079 fn test_upgrade_0_to_1() {
1080     const ALIAS1: &str = "test_upgrade_0_to_1_1";
1081     const ALIAS2: &str = "test_upgrade_0_to_1_2";
1082     const ALIAS3: &str = "test_upgrade_0_to_1_3";
1083     const UID: u32 = 33;
1084     let temp_dir = Arc::new(TempDir::new("test_upgrade_0_to_1").unwrap());
1085     let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
1086     let key_id_untouched1 =
1087         make_test_key_entry(&mut db, Domain::APP, UID as i64, ALIAS1, None).unwrap().id();
1088     let key_id_untouched2 =
1089         make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS2, false).unwrap().id();
1090     let key_id_deleted =
1091         make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS3, true).unwrap().id();
1092 
1093     let (_, key_entry) = db
1094         .load_key_entry(
1095             &KeyDescriptor {
1096                 domain: Domain::APP,
1097                 nspace: -1,
1098                 alias: Some(ALIAS1.to_string()),
1099                 blob: None,
1100             },
1101             KeyType::Client,
1102             KeyEntryLoadBits::BOTH,
1103             UID,
1104             |k, av| {
1105                 assert_eq!(Domain::APP, k.domain);
1106                 assert_eq!(UID as i64, k.nspace);
1107                 assert!(av.is_none());
1108                 Ok(())
1109             },
1110         )
1111         .unwrap();
1112     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
1113     let (_, key_entry) = db
1114         .load_key_entry(
1115             &KeyDescriptor {
1116                 domain: Domain::APP,
1117                 nspace: -1,
1118                 alias: Some(ALIAS2.to_string()),
1119                 blob: None,
1120             },
1121             KeyType::Client,
1122             KeyEntryLoadBits::BOTH,
1123             UID,
1124             |k, av| {
1125                 assert_eq!(Domain::APP, k.domain);
1126                 assert_eq!(UID as i64, k.nspace);
1127                 assert!(av.is_none());
1128                 Ok(())
1129             },
1130         )
1131         .unwrap();
1132     assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
1133     let (_, key_entry) = db
1134         .load_key_entry(
1135             &KeyDescriptor {
1136                 domain: Domain::APP,
1137                 nspace: -1,
1138                 alias: Some(ALIAS3.to_string()),
1139                 blob: None,
1140             },
1141             KeyType::Client,
1142             KeyEntryLoadBits::BOTH,
1143             UID,
1144             |k, av| {
1145                 assert_eq!(Domain::APP, k.domain);
1146                 assert_eq!(UID as i64, k.nspace);
1147                 assert!(av.is_none());
1148                 Ok(())
1149             },
1150         )
1151         .unwrap();
1152     assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_deleted, true));
1153 
1154     db.with_transaction(Immediate("TX_test"), |tx| KeystoreDB::from_0_to_1(tx).no_gc()).unwrap();
1155 
1156     let (_, key_entry) = db
1157         .load_key_entry(
1158             &KeyDescriptor {
1159                 domain: Domain::APP,
1160                 nspace: -1,
1161                 alias: Some(ALIAS1.to_string()),
1162                 blob: None,
1163             },
1164             KeyType::Client,
1165             KeyEntryLoadBits::BOTH,
1166             UID,
1167             |k, av| {
1168                 assert_eq!(Domain::APP, k.domain);
1169                 assert_eq!(UID as i64, k.nspace);
1170                 assert!(av.is_none());
1171                 Ok(())
1172             },
1173         )
1174         .unwrap();
1175     assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
1176     let (_, key_entry) = db
1177         .load_key_entry(
1178             &KeyDescriptor {
1179                 domain: Domain::APP,
1180                 nspace: -1,
1181                 alias: Some(ALIAS2.to_string()),
1182                 blob: None,
1183             },
1184             KeyType::Client,
1185             KeyEntryLoadBits::BOTH,
1186             UID,
1187             |k, av| {
1188                 assert_eq!(Domain::APP, k.domain);
1189                 assert_eq!(UID as i64, k.nspace);
1190                 assert!(av.is_none());
1191                 Ok(())
1192             },
1193         )
1194         .unwrap();
1195     assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
1196     assert_eq!(
1197         Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
1198         db.load_key_entry(
1199             &KeyDescriptor {
1200                 domain: Domain::APP,
1201                 nspace: -1,
1202                 alias: Some(ALIAS3.to_string()),
1203                 blob: None,
1204             },
1205             KeyType::Client,
1206             KeyEntryLoadBits::BOTH,
1207             UID,
1208             |k, av| {
1209                 assert_eq!(Domain::APP, k.domain);
1210                 assert_eq!(UID as i64, k.nspace);
1211                 assert!(av.is_none());
1212                 Ok(())
1213             },
1214         )
1215         .unwrap_err()
1216         .root_cause()
1217         .downcast_ref::<KsError>()
1218     );
1219 }
1220 
1221 static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
1222 
1223 #[test]
test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()>1224 fn test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()> {
1225     let handle = {
1226         let temp_dir = Arc::new(TempDir::new("id_lock_test")?);
1227         let temp_dir_clone = temp_dir.clone();
1228         let mut db = KeystoreDB::new(temp_dir.path(), None)?;
1229         let key_id = make_test_key_entry(&mut db, Domain::APP, 33, KEY_LOCK_TEST_ALIAS, None)
1230             .context("test_insert_and_load_full_keyentry_domain_app")?
1231             .0;
1232         let (_key_guard, key_entry) = db
1233             .load_key_entry(
1234                 &KeyDescriptor {
1235                     domain: Domain::APP,
1236                     nspace: 0,
1237                     alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
1238                     blob: None,
1239                 },
1240                 KeyType::Client,
1241                 KeyEntryLoadBits::BOTH,
1242                 33,
1243                 |_k, _av| Ok(()),
1244             )
1245             .unwrap();
1246         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
1247         let state = Arc::new(AtomicU8::new(1));
1248         let state2 = state.clone();
1249 
1250         // Spawning a second thread that attempts to acquire the key id lock
1251         // for the same key as the primary thread. The primary thread then
1252         // waits, thereby forcing the secondary thread into the second stage
1253         // of acquiring the lock (see KEY ID LOCK 2/2 above).
1254         // The test succeeds if the secondary thread observes the transition
1255         // of `state` from 1 to 2, despite having a whole second to overtake
1256         // the primary thread.
1257         let handle = thread::spawn(move || {
1258             let temp_dir = temp_dir_clone;
1259             let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
1260             assert!(db
1261                 .load_key_entry(
1262                     &KeyDescriptor {
1263                         domain: Domain::APP,
1264                         nspace: 0,
1265                         alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
1266                         blob: None,
1267                     },
1268                     KeyType::Client,
1269                     KeyEntryLoadBits::BOTH,
1270                     33,
1271                     |_k, _av| Ok(()),
1272                 )
1273                 .is_ok());
1274             // We should only see a 2 here because we can only return
1275             // from load_key_entry when the `_key_guard` expires,
1276             // which happens at the end of the scope.
1277             assert_eq!(2, state2.load(Ordering::Relaxed));
1278         });
1279 
1280         thread::sleep(std::time::Duration::from_millis(1000));
1281 
1282         assert_eq!(Ok(1), state.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed));
1283 
1284         // Return the handle from this scope so we can join with the
1285         // secondary thread after the key id lock has expired.
1286         handle
1287         // This is where the `_key_guard` goes out of scope,
1288         // which is the reason for concurrent load_key_entry on the same key
1289         // to unblock.
1290     };
1291     // Join with the secondary thread and unwrap, to propagate failing asserts to the
1292     // main test thread. We will not see failing asserts in secondary threads otherwise.
1293     handle.join().unwrap();
1294     Ok(())
1295 }
1296 
1297 #[test]
test_database_busy_error_code()1298 fn test_database_busy_error_code() {
1299     let temp_dir =
1300         TempDir::new("test_database_busy_error_code_").expect("Failed to create temp dir.");
1301 
1302     let mut db1 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database1.");
1303     let mut db2 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database2.");
1304 
1305     let _tx1 = db1
1306         .conn
1307         .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
1308         .expect("Failed to create first transaction.");
1309 
1310     let error = db2
1311         .conn
1312         .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
1313         .context("Transaction begin failed.")
1314         .expect_err("This should fail.");
1315     let root_cause = error.root_cause();
1316     if let Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) =
1317         root_cause.downcast_ref::<rusqlite::ffi::Error>()
1318     {
1319         return;
1320     }
1321     panic!(
1322         "Unexpected error {:?} \n{:?} \n{:?}",
1323         error,
1324         root_cause,
1325         root_cause.downcast_ref::<rusqlite::ffi::Error>()
1326     )
1327 }
1328 
1329 #[cfg(disabled)]
1330 #[test]
test_large_number_of_concurrent_db_manipulations() -> Result<()>1331 fn test_large_number_of_concurrent_db_manipulations() -> Result<()> {
1332     let temp_dir = Arc::new(
1333         TempDir::new("test_large_number_of_concurrent_db_manipulations_")
1334             .expect("Failed to create temp dir."),
1335     );
1336 
1337     let test_begin = Instant::now();
1338 
1339     const KEY_COUNT: u32 = 500u32;
1340     let mut db =
1341         new_test_db_with_gc(temp_dir.path(), |_, _| Ok(())).expect("Failed to open database.");
1342     const OPEN_DB_COUNT: u32 = 50u32;
1343 
1344     let mut actual_key_count = KEY_COUNT;
1345     // First insert KEY_COUNT keys.
1346     for count in 0..KEY_COUNT {
1347         if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
1348             actual_key_count = count;
1349             break;
1350         }
1351         let alias = format!("test_alias_{}", count);
1352         make_test_key_entry(&mut db, Domain::APP, 1, &alias, None)
1353             .expect("Failed to make key entry.");
1354     }
1355 
1356     // Insert more keys from a different thread and into a different namespace.
1357     let temp_dir1 = temp_dir.clone();
1358     let handle1 = thread::spawn(move || {
1359         let mut db =
1360             new_test_db_with_gc(temp_dir1.path(), |_, _| Ok(())).expect("Failed to open database.");
1361 
1362         for count in 0..actual_key_count {
1363             if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
1364                 return;
1365             }
1366             let alias = format!("test_alias_{}", count);
1367             make_test_key_entry(&mut db, Domain::APP, 2, &alias, None)
1368                 .expect("Failed to make key entry.");
1369         }
1370 
1371         // then unbind them again.
1372         for count in 0..actual_key_count {
1373             if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
1374                 return;
1375             }
1376             let key = KeyDescriptor {
1377                 domain: Domain::APP,
1378                 nspace: -1,
1379                 alias: Some(format!("test_alias_{}", count)),
1380                 blob: None,
1381             };
1382             db.unbind_key(&key, KeyType::Client, 2, |_, _| Ok(())).expect("Unbind Failed.");
1383         }
1384     });
1385 
1386     // And start unbinding the first set of keys.
1387     let temp_dir2 = temp_dir.clone();
1388     let handle2 = thread::spawn(move || {
1389         let mut db =
1390             new_test_db_with_gc(temp_dir2.path(), |_, _| Ok(())).expect("Failed to open database.");
1391 
1392         for count in 0..actual_key_count {
1393             if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
1394                 return;
1395             }
1396             let key = KeyDescriptor {
1397                 domain: Domain::APP,
1398                 nspace: -1,
1399                 alias: Some(format!("test_alias_{}", count)),
1400                 blob: None,
1401             };
1402             db.unbind_key(&key, KeyType::Client, 1, |_, _| Ok(())).expect("Unbind Failed.");
1403         }
1404     });
1405 
1406     // While a lot of inserting and deleting is going on we have to open database connections
1407     // successfully and use them.
1408     // This clone is not redundant, because temp_dir needs to be kept alive until db goes
1409     // out of scope.
1410     #[allow(clippy::redundant_clone)]
1411     let temp_dir4 = temp_dir.clone();
1412     let handle4 = thread::spawn(move || {
1413         for count in 0..OPEN_DB_COUNT {
1414             if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
1415                 return;
1416             }
1417             let mut db = new_test_db_with_gc(temp_dir4.path(), |_, _| Ok(()))
1418                 .expect("Failed to open database.");
1419 
1420             let alias = format!("test_alias_{}", count);
1421             make_test_key_entry(&mut db, Domain::APP, 3, &alias, None)
1422                 .expect("Failed to make key entry.");
1423             let key =
1424                 KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None };
1425             db.unbind_key(&key, KeyType::Client, 3, |_, _| Ok(())).expect("Unbind Failed.");
1426         }
1427     });
1428 
1429     handle1.join().expect("Thread 1 panicked.");
1430     handle2.join().expect("Thread 2 panicked.");
1431     handle4.join().expect("Thread 4 panicked.");
1432 
1433     Ok(())
1434 }
1435 
1436 #[test]
list() -> Result<()>1437 fn list() -> Result<()> {
1438     let temp_dir = TempDir::new("list_test")?;
1439     let mut db = KeystoreDB::new(temp_dir.path(), None)?;
1440     static LIST_O_ENTRIES: &[(Domain, i64, &str)] = &[
1441         (Domain::APP, 1, "test1"),
1442         (Domain::APP, 1, "test2"),
1443         (Domain::APP, 1, "test3"),
1444         (Domain::APP, 1, "test4"),
1445         (Domain::APP, 1, "test5"),
1446         (Domain::APP, 1, "test6"),
1447         (Domain::APP, 1, "test7"),
1448         (Domain::APP, 2, "test1"),
1449         (Domain::APP, 2, "test2"),
1450         (Domain::APP, 2, "test3"),
1451         (Domain::APP, 2, "test4"),
1452         (Domain::APP, 2, "test5"),
1453         (Domain::APP, 2, "test6"),
1454         (Domain::APP, 2, "test8"),
1455         (Domain::SELINUX, 100, "test1"),
1456         (Domain::SELINUX, 100, "test2"),
1457         (Domain::SELINUX, 100, "test3"),
1458         (Domain::SELINUX, 100, "test4"),
1459         (Domain::SELINUX, 100, "test5"),
1460         (Domain::SELINUX, 100, "test6"),
1461         (Domain::SELINUX, 100, "test9"),
1462     ];
1463 
1464     let list_o_keys: Vec<(i64, i64)> = LIST_O_ENTRIES
1465         .iter()
1466         .map(|(domain, ns, alias)| {
1467             let entry =
1468                 make_test_key_entry(&mut db, *domain, *ns, alias, None).unwrap_or_else(|e| {
1469                     panic!("Failed to insert {:?} {} {}. Error {:?}", domain, ns, alias, e)
1470                 });
1471             (entry.id(), *ns)
1472         })
1473         .collect();
1474 
1475     for (domain, namespace) in
1476         &[(Domain::APP, 1i64), (Domain::APP, 2i64), (Domain::SELINUX, 100i64)]
1477     {
1478         let mut list_o_descriptors: Vec<KeyDescriptor> = LIST_O_ENTRIES
1479             .iter()
1480             .filter_map(|(domain, ns, alias)| match ns {
1481                 ns if *ns == *namespace => Some(KeyDescriptor {
1482                     domain: *domain,
1483                     nspace: *ns,
1484                     alias: Some(alias.to_string()),
1485                     blob: None,
1486                 }),
1487                 _ => None,
1488             })
1489             .collect();
1490         list_o_descriptors.sort();
1491         let mut list_result = db.list_past_alias(*domain, *namespace, KeyType::Client, None)?;
1492         list_result.sort();
1493         assert_eq!(list_o_descriptors, list_result);
1494 
1495         let mut list_o_ids: Vec<i64> = list_o_descriptors
1496             .into_iter()
1497             .map(|d| {
1498                 let (_, entry) = db
1499                     .load_key_entry(
1500                         &d,
1501                         KeyType::Client,
1502                         KeyEntryLoadBits::NONE,
1503                         *namespace as u32,
1504                         |_, _| Ok(()),
1505                     )
1506                     .unwrap();
1507                 entry.id()
1508             })
1509             .collect();
1510         list_o_ids.sort_unstable();
1511         let mut loaded_entries: Vec<i64> = list_o_keys
1512             .iter()
1513             .filter_map(|(id, ns)| match ns {
1514                 ns if *ns == *namespace => Some(*id),
1515                 _ => None,
1516             })
1517             .collect();
1518         loaded_entries.sort_unstable();
1519         assert_eq!(list_o_ids, loaded_entries);
1520     }
1521     assert_eq!(
1522         Vec::<KeyDescriptor>::new(),
1523         db.list_past_alias(Domain::SELINUX, 101, KeyType::Client, None)?
1524     );
1525 
1526     Ok(())
1527 }
1528 
1529 // Helpers
1530 
1531 // Checks that the given result is an error containing the given string.
check_result_is_error_containing_string<T>(result: Result<T>, target: &str)1532 fn check_result_is_error_containing_string<T>(result: Result<T>, target: &str) {
1533     let error_str =
1534         format!("{:#?}", result.err().unwrap_or_else(|| panic!("Expected the error: {}", target)));
1535     assert!(
1536         error_str.contains(target),
1537         "The string \"{}\" should contain \"{}\"",
1538         error_str,
1539         target
1540     );
1541 }
1542 
1543 #[derive(Debug, PartialEq)]
1544 struct KeyEntryRow {
1545     id: i64,
1546     key_type: KeyType,
1547     domain: Option<Domain>,
1548     namespace: Option<i64>,
1549     alias: Option<String>,
1550     state: KeyLifeCycle,
1551     km_uuid: Option<Uuid>,
1552 }
1553 
get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>>1554 fn get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>> {
1555     db.conn
1556         .prepare("SELECT * FROM persistent.keyentry;")?
1557         .query_map([], |row| {
1558             Ok(KeyEntryRow {
1559                 id: row.get(0)?,
1560                 key_type: row.get(1)?,
1561                 domain: row.get::<_, Option<_>>(2)?.map(Domain),
1562                 namespace: row.get(3)?,
1563                 alias: row.get(4)?,
1564                 state: row.get(5)?,
1565                 km_uuid: row.get(6)?,
1566             })
1567         })?
1568         .map(|r| r.context("Could not read keyentry row."))
1569         .collect::<Result<Vec<_>>>()
1570 }
1571 
make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter>1572 fn make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter> {
1573     make_test_params_with_sids(max_usage_count, &[42])
1574 }
1575 
1576 // Note: The parameters and SecurityLevel associations are nonsensical. This
1577 // collection is only used to check if the parameters are preserved as expected by the
1578 // database.
make_test_params_with_sids( max_usage_count: Option<i32>, user_secure_ids: &[i64], ) -> Vec<KeyParameter>1579 fn make_test_params_with_sids(
1580     max_usage_count: Option<i32>,
1581     user_secure_ids: &[i64],
1582 ) -> Vec<KeyParameter> {
1583     let mut params = vec![
1584         KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::TRUSTED_ENVIRONMENT),
1585         KeyParameter::new(
1586             KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
1587             SecurityLevel::TRUSTED_ENVIRONMENT,
1588         ),
1589         KeyParameter::new(
1590             KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
1591             SecurityLevel::TRUSTED_ENVIRONMENT,
1592         ),
1593         KeyParameter::new(
1594             KeyParameterValue::Algorithm(Algorithm::RSA),
1595             SecurityLevel::TRUSTED_ENVIRONMENT,
1596         ),
1597         KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::TRUSTED_ENVIRONMENT),
1598         KeyParameter::new(
1599             KeyParameterValue::BlockMode(BlockMode::ECB),
1600             SecurityLevel::TRUSTED_ENVIRONMENT,
1601         ),
1602         KeyParameter::new(
1603             KeyParameterValue::BlockMode(BlockMode::GCM),
1604             SecurityLevel::TRUSTED_ENVIRONMENT,
1605         ),
1606         KeyParameter::new(KeyParameterValue::Digest(Digest::NONE), SecurityLevel::STRONGBOX),
1607         KeyParameter::new(
1608             KeyParameterValue::Digest(Digest::MD5),
1609             SecurityLevel::TRUSTED_ENVIRONMENT,
1610         ),
1611         KeyParameter::new(
1612             KeyParameterValue::Digest(Digest::SHA_2_224),
1613             SecurityLevel::TRUSTED_ENVIRONMENT,
1614         ),
1615         KeyParameter::new(KeyParameterValue::Digest(Digest::SHA_2_256), SecurityLevel::STRONGBOX),
1616         KeyParameter::new(
1617             KeyParameterValue::PaddingMode(PaddingMode::NONE),
1618             SecurityLevel::TRUSTED_ENVIRONMENT,
1619         ),
1620         KeyParameter::new(
1621             KeyParameterValue::PaddingMode(PaddingMode::RSA_OAEP),
1622             SecurityLevel::TRUSTED_ENVIRONMENT,
1623         ),
1624         KeyParameter::new(
1625             KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
1626             SecurityLevel::STRONGBOX,
1627         ),
1628         KeyParameter::new(
1629             KeyParameterValue::PaddingMode(PaddingMode::RSA_PKCS1_1_5_SIGN),
1630             SecurityLevel::TRUSTED_ENVIRONMENT,
1631         ),
1632         KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::TRUSTED_ENVIRONMENT),
1633         KeyParameter::new(KeyParameterValue::MinMacLength(256), SecurityLevel::STRONGBOX),
1634         KeyParameter::new(
1635             KeyParameterValue::EcCurve(EcCurve::P_224),
1636             SecurityLevel::TRUSTED_ENVIRONMENT,
1637         ),
1638         KeyParameter::new(KeyParameterValue::EcCurve(EcCurve::P_256), SecurityLevel::STRONGBOX),
1639         KeyParameter::new(
1640             KeyParameterValue::EcCurve(EcCurve::P_384),
1641             SecurityLevel::TRUSTED_ENVIRONMENT,
1642         ),
1643         KeyParameter::new(
1644             KeyParameterValue::EcCurve(EcCurve::P_521),
1645             SecurityLevel::TRUSTED_ENVIRONMENT,
1646         ),
1647         KeyParameter::new(
1648             KeyParameterValue::RSAPublicExponent(3),
1649             SecurityLevel::TRUSTED_ENVIRONMENT,
1650         ),
1651         KeyParameter::new(KeyParameterValue::IncludeUniqueID, SecurityLevel::TRUSTED_ENVIRONMENT),
1652         KeyParameter::new(KeyParameterValue::BootLoaderOnly, SecurityLevel::STRONGBOX),
1653         KeyParameter::new(KeyParameterValue::RollbackResistance, SecurityLevel::STRONGBOX),
1654         KeyParameter::new(KeyParameterValue::ActiveDateTime(1234567890), SecurityLevel::STRONGBOX),
1655         KeyParameter::new(
1656             KeyParameterValue::OriginationExpireDateTime(1234567890),
1657             SecurityLevel::TRUSTED_ENVIRONMENT,
1658         ),
1659         KeyParameter::new(
1660             KeyParameterValue::UsageExpireDateTime(1234567890),
1661             SecurityLevel::TRUSTED_ENVIRONMENT,
1662         ),
1663         KeyParameter::new(
1664             KeyParameterValue::MinSecondsBetweenOps(1234567890),
1665             SecurityLevel::TRUSTED_ENVIRONMENT,
1666         ),
1667         KeyParameter::new(
1668             KeyParameterValue::MaxUsesPerBoot(1234567890),
1669             SecurityLevel::TRUSTED_ENVIRONMENT,
1670         ),
1671         KeyParameter::new(KeyParameterValue::UserID(1), SecurityLevel::STRONGBOX),
1672         KeyParameter::new(KeyParameterValue::NoAuthRequired, SecurityLevel::TRUSTED_ENVIRONMENT),
1673         KeyParameter::new(
1674             KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType::PASSWORD),
1675             SecurityLevel::TRUSTED_ENVIRONMENT,
1676         ),
1677         KeyParameter::new(KeyParameterValue::AuthTimeout(1234567890), SecurityLevel::SOFTWARE),
1678         KeyParameter::new(KeyParameterValue::AllowWhileOnBody, SecurityLevel::SOFTWARE),
1679         KeyParameter::new(
1680             KeyParameterValue::TrustedUserPresenceRequired,
1681             SecurityLevel::TRUSTED_ENVIRONMENT,
1682         ),
1683         KeyParameter::new(
1684             KeyParameterValue::TrustedConfirmationRequired,
1685             SecurityLevel::TRUSTED_ENVIRONMENT,
1686         ),
1687         KeyParameter::new(
1688             KeyParameterValue::UnlockedDeviceRequired,
1689             SecurityLevel::TRUSTED_ENVIRONMENT,
1690         ),
1691         KeyParameter::new(
1692             KeyParameterValue::ApplicationID(vec![1u8, 2u8, 3u8, 4u8]),
1693             SecurityLevel::SOFTWARE,
1694         ),
1695         KeyParameter::new(
1696             KeyParameterValue::ApplicationData(vec![4u8, 3u8, 2u8, 1u8]),
1697             SecurityLevel::SOFTWARE,
1698         ),
1699         KeyParameter::new(
1700             KeyParameterValue::CreationDateTime(12345677890),
1701             SecurityLevel::SOFTWARE,
1702         ),
1703         KeyParameter::new(
1704             KeyParameterValue::KeyOrigin(KeyOrigin::GENERATED),
1705             SecurityLevel::TRUSTED_ENVIRONMENT,
1706         ),
1707         KeyParameter::new(
1708             KeyParameterValue::RootOfTrust(vec![3u8, 2u8, 1u8, 4u8]),
1709             SecurityLevel::TRUSTED_ENVIRONMENT,
1710         ),
1711         KeyParameter::new(KeyParameterValue::OSVersion(1), SecurityLevel::TRUSTED_ENVIRONMENT),
1712         KeyParameter::new(KeyParameterValue::OSPatchLevel(2), SecurityLevel::SOFTWARE),
1713         KeyParameter::new(
1714             KeyParameterValue::UniqueID(vec![4u8, 3u8, 1u8, 2u8]),
1715             SecurityLevel::SOFTWARE,
1716         ),
1717         KeyParameter::new(
1718             KeyParameterValue::AttestationChallenge(vec![4u8, 3u8, 1u8, 2u8]),
1719             SecurityLevel::TRUSTED_ENVIRONMENT,
1720         ),
1721         KeyParameter::new(
1722             KeyParameterValue::AttestationApplicationID(vec![4u8, 3u8, 1u8, 2u8]),
1723             SecurityLevel::TRUSTED_ENVIRONMENT,
1724         ),
1725         KeyParameter::new(
1726             KeyParameterValue::AttestationIdBrand(vec![4u8, 3u8, 1u8, 2u8]),
1727             SecurityLevel::TRUSTED_ENVIRONMENT,
1728         ),
1729         KeyParameter::new(
1730             KeyParameterValue::AttestationIdDevice(vec![4u8, 3u8, 1u8, 2u8]),
1731             SecurityLevel::TRUSTED_ENVIRONMENT,
1732         ),
1733         KeyParameter::new(
1734             KeyParameterValue::AttestationIdProduct(vec![4u8, 3u8, 1u8, 2u8]),
1735             SecurityLevel::TRUSTED_ENVIRONMENT,
1736         ),
1737         KeyParameter::new(
1738             KeyParameterValue::AttestationIdSerial(vec![4u8, 3u8, 1u8, 2u8]),
1739             SecurityLevel::TRUSTED_ENVIRONMENT,
1740         ),
1741         KeyParameter::new(
1742             KeyParameterValue::AttestationIdIMEI(vec![4u8, 3u8, 1u8, 2u8]),
1743             SecurityLevel::TRUSTED_ENVIRONMENT,
1744         ),
1745         KeyParameter::new(
1746             KeyParameterValue::AttestationIdSecondIMEI(vec![4u8, 3u8, 1u8, 2u8]),
1747             SecurityLevel::TRUSTED_ENVIRONMENT,
1748         ),
1749         KeyParameter::new(
1750             KeyParameterValue::AttestationIdMEID(vec![4u8, 3u8, 1u8, 2u8]),
1751             SecurityLevel::TRUSTED_ENVIRONMENT,
1752         ),
1753         KeyParameter::new(
1754             KeyParameterValue::AttestationIdManufacturer(vec![4u8, 3u8, 1u8, 2u8]),
1755             SecurityLevel::TRUSTED_ENVIRONMENT,
1756         ),
1757         KeyParameter::new(
1758             KeyParameterValue::AttestationIdModel(vec![4u8, 3u8, 1u8, 2u8]),
1759             SecurityLevel::TRUSTED_ENVIRONMENT,
1760         ),
1761         KeyParameter::new(
1762             KeyParameterValue::VendorPatchLevel(3),
1763             SecurityLevel::TRUSTED_ENVIRONMENT,
1764         ),
1765         KeyParameter::new(KeyParameterValue::BootPatchLevel(4), SecurityLevel::TRUSTED_ENVIRONMENT),
1766         KeyParameter::new(
1767             KeyParameterValue::AssociatedData(vec![4u8, 3u8, 1u8, 2u8]),
1768             SecurityLevel::TRUSTED_ENVIRONMENT,
1769         ),
1770         KeyParameter::new(
1771             KeyParameterValue::Nonce(vec![4u8, 3u8, 1u8, 2u8]),
1772             SecurityLevel::TRUSTED_ENVIRONMENT,
1773         ),
1774         KeyParameter::new(KeyParameterValue::MacLength(256), SecurityLevel::TRUSTED_ENVIRONMENT),
1775         KeyParameter::new(
1776             KeyParameterValue::ResetSinceIdRotation,
1777             SecurityLevel::TRUSTED_ENVIRONMENT,
1778         ),
1779         KeyParameter::new(
1780             KeyParameterValue::ConfirmationToken(vec![5u8, 5u8, 5u8, 5u8]),
1781             SecurityLevel::TRUSTED_ENVIRONMENT,
1782         ),
1783     ];
1784     if let Some(value) = max_usage_count {
1785         params.push(KeyParameter::new(
1786             KeyParameterValue::UsageCountLimit(value),
1787             SecurityLevel::SOFTWARE,
1788         ));
1789     }
1790 
1791     for sid in user_secure_ids.iter() {
1792         params.push(KeyParameter::new(
1793             KeyParameterValue::UserSecureID(*sid),
1794             SecurityLevel::STRONGBOX,
1795         ));
1796     }
1797     params
1798 }
1799 
make_test_key_entry( db: &mut KeystoreDB, domain: Domain, namespace: i64, alias: &str, max_usage_count: Option<i32>, ) -> Result<KeyIdGuard>1800 pub fn make_test_key_entry(
1801     db: &mut KeystoreDB,
1802     domain: Domain,
1803     namespace: i64,
1804     alias: &str,
1805     max_usage_count: Option<i32>,
1806 ) -> Result<KeyIdGuard> {
1807     make_test_key_entry_with_sids(db, domain, namespace, alias, max_usage_count, &[42])
1808 }
1809 
make_test_key_entry_with_sids( db: &mut KeystoreDB, domain: Domain, namespace: i64, alias: &str, max_usage_count: Option<i32>, sids: &[i64], ) -> Result<KeyIdGuard>1810 pub fn make_test_key_entry_with_sids(
1811     db: &mut KeystoreDB,
1812     domain: Domain,
1813     namespace: i64,
1814     alias: &str,
1815     max_usage_count: Option<i32>,
1816     sids: &[i64],
1817 ) -> Result<KeyIdGuard> {
1818     let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
1819     let mut blob_metadata = BlobMetaData::new();
1820     blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
1821     blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
1822     blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
1823     blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
1824     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
1825 
1826     db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), Some(&blob_metadata))?;
1827     db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
1828     db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
1829 
1830     let params = make_test_params_with_sids(max_usage_count, sids);
1831     db.insert_keyparameter(&key_id, &params)?;
1832 
1833     let mut metadata = KeyMetaData::new();
1834     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
1835     db.insert_key_metadata(&key_id, &metadata)?;
1836     rebind_alias(db, &key_id, alias, domain, namespace)?;
1837     Ok(key_id)
1838 }
1839 
make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry1840 fn make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry {
1841     let params = make_test_params(max_usage_count);
1842 
1843     let mut blob_metadata = BlobMetaData::new();
1844     blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
1845     blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
1846     blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
1847     blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
1848     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
1849 
1850     let mut metadata = KeyMetaData::new();
1851     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
1852 
1853     KeyEntry {
1854         id: key_id,
1855         key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
1856         cert: Some(TEST_CERT_BLOB.to_vec()),
1857         cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
1858         km_uuid: KEYSTORE_UUID,
1859         parameters: params,
1860         metadata,
1861         pure_cert: false,
1862     }
1863 }
1864 
make_bootlevel_key_entry( db: &mut KeystoreDB, domain: Domain, namespace: i64, alias: &str, logical_only: bool, ) -> Result<KeyIdGuard>1865 pub fn make_bootlevel_key_entry(
1866     db: &mut KeystoreDB,
1867     domain: Domain,
1868     namespace: i64,
1869     alias: &str,
1870     logical_only: bool,
1871 ) -> Result<KeyIdGuard> {
1872     let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
1873     let mut blob_metadata = BlobMetaData::new();
1874     if !logical_only {
1875         blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
1876     }
1877     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
1878 
1879     db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), Some(&blob_metadata))?;
1880     db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
1881     db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
1882 
1883     let mut params = make_test_params(None);
1884     params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
1885 
1886     db.insert_keyparameter(&key_id, &params)?;
1887 
1888     let mut metadata = KeyMetaData::new();
1889     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
1890     db.insert_key_metadata(&key_id, &metadata)?;
1891     rebind_alias(db, &key_id, alias, domain, namespace)?;
1892     Ok(key_id)
1893 }
1894 
1895 // Creates an app key that is marked as being superencrypted by the given
1896 // super key ID and that has the given authentication and unlocked device
1897 // parameters. This does not actually superencrypt the key blob.
make_superencrypted_key_entry( db: &mut KeystoreDB, namespace: i64, alias: &str, requires_authentication: bool, requires_unlocked_device: bool, super_key_id: i64, ) -> Result<KeyIdGuard>1898 fn make_superencrypted_key_entry(
1899     db: &mut KeystoreDB,
1900     namespace: i64,
1901     alias: &str,
1902     requires_authentication: bool,
1903     requires_unlocked_device: bool,
1904     super_key_id: i64,
1905 ) -> Result<KeyIdGuard> {
1906     let domain = Domain::APP;
1907     let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
1908 
1909     let mut blob_metadata = BlobMetaData::new();
1910     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
1911     blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key_id)));
1912     db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), Some(&blob_metadata))?;
1913 
1914     let mut params = vec![];
1915     if requires_unlocked_device {
1916         params.push(KeyParameter::new(
1917             KeyParameterValue::UnlockedDeviceRequired,
1918             SecurityLevel::TRUSTED_ENVIRONMENT,
1919         ));
1920     }
1921     if requires_authentication {
1922         params.push(KeyParameter::new(
1923             KeyParameterValue::UserSecureID(42),
1924             SecurityLevel::TRUSTED_ENVIRONMENT,
1925         ));
1926     }
1927     db.insert_keyparameter(&key_id, &params)?;
1928 
1929     let mut metadata = KeyMetaData::new();
1930     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
1931     db.insert_key_metadata(&key_id, &metadata)?;
1932 
1933     rebind_alias(db, &key_id, alias, domain, namespace)?;
1934     Ok(key_id)
1935 }
1936 
make_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry1937 fn make_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry {
1938     let mut params = make_test_params(None);
1939     params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
1940 
1941     let mut blob_metadata = BlobMetaData::new();
1942     if !logical_only {
1943         blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
1944     }
1945     blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
1946 
1947     let mut metadata = KeyMetaData::new();
1948     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
1949 
1950     KeyEntry {
1951         id: key_id,
1952         key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
1953         cert: Some(TEST_CERT_BLOB.to_vec()),
1954         cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
1955         km_uuid: KEYSTORE_UUID,
1956         parameters: params,
1957         metadata,
1958         pure_cert: false,
1959     }
1960 }
1961 
debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()>1962 fn debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()> {
1963     let mut stmt = db.conn.prepare(
1964         "SELECT id, key_type, domain, namespace, alias, state, km_uuid FROM persistent.keyentry;",
1965     )?;
1966     let rows =
1967         stmt.query_map::<(i64, KeyType, i32, i64, String, KeyLifeCycle, Uuid), _, _>([], |row| {
1968             Ok((
1969                 row.get(0)?,
1970                 row.get(1)?,
1971                 row.get(2)?,
1972                 row.get(3)?,
1973                 row.get(4)?,
1974                 row.get(5)?,
1975                 row.get(6)?,
1976             ))
1977         })?;
1978 
1979     println!("Key entry table rows:");
1980     for r in rows {
1981         let (id, key_type, domain, namespace, alias, state, km_uuid) = r.unwrap();
1982         println!(
1983             "    id: {} KeyType: {:?} Domain: {} Namespace: {} Alias: {} State: {:?} KmUuid: {:?}",
1984             id, key_type, domain, namespace, alias, state, km_uuid
1985         );
1986     }
1987     Ok(())
1988 }
1989 
debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()>1990 fn debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()> {
1991     let mut stmt =
1992         db.conn.prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
1993     let rows = stmt.query_map::<(i64, i64, i64, i64), _, _>([], |row| {
1994         Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
1995     })?;
1996 
1997     println!("Grant table rows:");
1998     for r in rows {
1999         let (id, gt, ki, av) = r.unwrap();
2000         println!("    id: {} grantee: {} key_id: {} access_vector: {}", id, gt, ki, av);
2001     }
2002     Ok(())
2003 }
2004 
2005 // Use a custom random number generator that repeats each number once.
2006 // This allows us to test repeated elements.
2007 
2008 thread_local! {
2009     static RANDOM_COUNTER: RefCell<i64> = const { RefCell::new(0) };
2010 }
2011 
reset_random()2012 fn reset_random() {
2013     RANDOM_COUNTER.with(|counter| {
2014         *counter.borrow_mut() = 0;
2015     })
2016 }
2017 
random() -> i642018 pub fn random() -> i64 {
2019     RANDOM_COUNTER.with(|counter| {
2020         let result = *counter.borrow() / 2;
2021         *counter.borrow_mut() += 1;
2022         result
2023     })
2024 }
2025 
2026 #[test]
test_unbind_keys_for_user() -> Result<()>2027 fn test_unbind_keys_for_user() -> Result<()> {
2028     let mut db = new_test_db()?;
2029     db.unbind_keys_for_user(1)?;
2030 
2031     make_test_key_entry(&mut db, Domain::APP, 210000, TEST_ALIAS, None)?;
2032     make_test_key_entry(&mut db, Domain::APP, 110000, TEST_ALIAS, None)?;
2033     db.unbind_keys_for_user(2)?;
2034 
2035     assert_eq!(1, db.list_past_alias(Domain::APP, 110000, KeyType::Client, None)?.len());
2036     assert_eq!(0, db.list_past_alias(Domain::APP, 210000, KeyType::Client, None)?.len());
2037 
2038     db.unbind_keys_for_user(1)?;
2039     assert_eq!(0, db.list_past_alias(Domain::APP, 110000, KeyType::Client, None)?.len());
2040 
2041     Ok(())
2042 }
2043 
2044 #[test]
test_unbind_keys_for_user_removes_superkeys() -> Result<()>2045 fn test_unbind_keys_for_user_removes_superkeys() -> Result<()> {
2046     let mut db = new_test_db()?;
2047     let super_key = keystore2_crypto::generate_aes256_key()?;
2048     let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
2049     let (encrypted_super_key, metadata) = SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
2050 
2051     let key_name_enc = SuperKeyType {
2052         alias: "test_super_key_1",
2053         algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
2054         name: "test_super_key_1",
2055     };
2056 
2057     let key_name_nonenc = SuperKeyType {
2058         alias: "test_super_key_2",
2059         algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
2060         name: "test_super_key_2",
2061     };
2062 
2063     // Install two super keys.
2064     db.store_super_key(1, &key_name_nonenc, &super_key, &BlobMetaData::new(), &KeyMetaData::new())?;
2065     db.store_super_key(1, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
2066 
2067     // Check that both can be found in the database.
2068     assert!(db.load_super_key(&key_name_enc, 1)?.is_some());
2069     assert!(db.load_super_key(&key_name_nonenc, 1)?.is_some());
2070 
2071     // Install the same keys for a different user.
2072     db.store_super_key(2, &key_name_nonenc, &super_key, &BlobMetaData::new(), &KeyMetaData::new())?;
2073     db.store_super_key(2, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
2074 
2075     // Check that the second pair of keys can be found in the database.
2076     assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
2077     assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
2078 
2079     // Delete all keys for user 1.
2080     db.unbind_keys_for_user(1)?;
2081 
2082     // All of user 1's keys should be gone.
2083     assert!(db.load_super_key(&key_name_enc, 1)?.is_none());
2084     assert!(db.load_super_key(&key_name_nonenc, 1)?.is_none());
2085 
2086     // User 2's keys should not have been touched.
2087     assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
2088     assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
2089 
2090     Ok(())
2091 }
2092 
app_key_exists(db: &mut KeystoreDB, nspace: i64, alias: &str) -> Result<bool>2093 fn app_key_exists(db: &mut KeystoreDB, nspace: i64, alias: &str) -> Result<bool> {
2094     db.key_exists(Domain::APP, nspace, alias, KeyType::Client)
2095 }
2096 
2097 // Tests the unbind_auth_bound_keys_for_user() function.
2098 #[test]
test_unbind_auth_bound_keys_for_user() -> Result<()>2099 fn test_unbind_auth_bound_keys_for_user() -> Result<()> {
2100     let mut db = new_test_db()?;
2101     let user_id = 1;
2102     let nspace: i64 = (user_id * AID_USER_OFFSET).into();
2103     let other_user_id = 2;
2104     let other_user_nspace: i64 = (other_user_id * AID_USER_OFFSET).into();
2105     let super_key_type = &USER_AFTER_FIRST_UNLOCK_SUPER_KEY;
2106 
2107     // Create a superencryption key.
2108     let super_key = keystore2_crypto::generate_aes256_key()?;
2109     let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
2110     let (encrypted_super_key, blob_metadata) =
2111         SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
2112     db.store_super_key(
2113         user_id,
2114         super_key_type,
2115         &encrypted_super_key,
2116         &blob_metadata,
2117         &KeyMetaData::new(),
2118     )?;
2119     let super_key_id = db.load_super_key(super_key_type, user_id)?.unwrap().0 .0;
2120 
2121     // Store 4 superencrypted app keys, one for each possible combination of
2122     // (authentication required, unlocked device required).
2123     make_superencrypted_key_entry(&mut db, nspace, "noauth_noud", false, false, super_key_id)?;
2124     make_superencrypted_key_entry(&mut db, nspace, "noauth_ud", false, true, super_key_id)?;
2125     make_superencrypted_key_entry(&mut db, nspace, "auth_noud", true, false, super_key_id)?;
2126     make_superencrypted_key_entry(&mut db, nspace, "auth_ud", true, true, super_key_id)?;
2127     assert!(app_key_exists(&mut db, nspace, "noauth_noud")?);
2128     assert!(app_key_exists(&mut db, nspace, "noauth_ud")?);
2129     assert!(app_key_exists(&mut db, nspace, "auth_noud")?);
2130     assert!(app_key_exists(&mut db, nspace, "auth_ud")?);
2131 
2132     // Also store a key for a different user that requires authentication.
2133     make_superencrypted_key_entry(&mut db, other_user_nspace, "auth_ud", true, true, super_key_id)?;
2134 
2135     db.unbind_auth_bound_keys_for_user(user_id)?;
2136 
2137     // Verify that only the user's app keys that require authentication were
2138     // deleted. Keys that require an unlocked device but not authentication
2139     // should *not* have been deleted, nor should the super key have been
2140     // deleted, nor should other users' keys have been deleted.
2141     assert!(db.load_super_key(super_key_type, user_id)?.is_some());
2142     assert!(app_key_exists(&mut db, nspace, "noauth_noud")?);
2143     assert!(app_key_exists(&mut db, nspace, "noauth_ud")?);
2144     assert!(!app_key_exists(&mut db, nspace, "auth_noud")?);
2145     assert!(!app_key_exists(&mut db, nspace, "auth_ud")?);
2146     assert!(app_key_exists(&mut db, other_user_nspace, "auth_ud")?);
2147 
2148     Ok(())
2149 }
2150 
2151 #[test]
test_store_super_key() -> Result<()>2152 fn test_store_super_key() -> Result<()> {
2153     let mut db = new_test_db()?;
2154     let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
2155     let super_key = keystore2_crypto::generate_aes256_key()?;
2156     let secret_bytes = b"keystore2 is great.";
2157     let (encrypted_secret, iv, tag) = keystore2_crypto::aes_gcm_encrypt(secret_bytes, &super_key)?;
2158 
2159     let (encrypted_super_key, metadata) = SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
2160     db.store_super_key(
2161         1,
2162         &USER_AFTER_FIRST_UNLOCK_SUPER_KEY,
2163         &encrypted_super_key,
2164         &metadata,
2165         &KeyMetaData::new(),
2166     )?;
2167 
2168     // Check if super key exists.
2169     assert!(db.key_exists(
2170         Domain::APP,
2171         1,
2172         USER_AFTER_FIRST_UNLOCK_SUPER_KEY.alias,
2173         KeyType::Super
2174     )?);
2175 
2176     let (_, key_entry) = db.load_super_key(&USER_AFTER_FIRST_UNLOCK_SUPER_KEY, 1)?.unwrap();
2177     let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(
2178         USER_AFTER_FIRST_UNLOCK_SUPER_KEY.algorithm,
2179         key_entry,
2180         &pw,
2181         None,
2182     )?;
2183 
2184     let decrypted_secret_bytes = loaded_super_key.decrypt(&encrypted_secret, &iv, &tag)?;
2185     assert_eq!(secret_bytes, &*decrypted_secret_bytes);
2186 
2187     Ok(())
2188 }
2189 
get_valid_statsd_storage_types() -> Vec<MetricsStorage>2190 fn get_valid_statsd_storage_types() -> Vec<MetricsStorage> {
2191     vec![
2192         MetricsStorage::KEY_ENTRY,
2193         MetricsStorage::KEY_ENTRY_ID_INDEX,
2194         MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
2195         MetricsStorage::BLOB_ENTRY,
2196         MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
2197         MetricsStorage::KEY_PARAMETER,
2198         MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX,
2199         MetricsStorage::KEY_METADATA,
2200         MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX,
2201         MetricsStorage::GRANT,
2202         MetricsStorage::AUTH_TOKEN,
2203         MetricsStorage::BLOB_METADATA,
2204         MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
2205     ]
2206 }
2207 
2208 /// Perform a simple check to ensure that we can query all the storage types
2209 /// that are supported by the DB. Check for reasonable values.
2210 #[test]
test_query_all_valid_table_sizes() -> Result<()>2211 fn test_query_all_valid_table_sizes() -> Result<()> {
2212     const PAGE_SIZE: i32 = 4096;
2213 
2214     let mut db = new_test_db()?;
2215 
2216     for t in get_valid_statsd_storage_types() {
2217         let stat = db.get_storage_stat(t)?;
2218         // AuthToken can be less than a page since it's in a btree, not sqlite
2219         // TODO(b/187474736) stop using if-let here
2220         if let MetricsStorage::AUTH_TOKEN = t {
2221         } else {
2222             assert!(stat.size >= PAGE_SIZE);
2223         }
2224         assert!(stat.size >= stat.unused_size);
2225     }
2226 
2227     Ok(())
2228 }
2229 
get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats>2230 fn get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats> {
2231     get_valid_statsd_storage_types()
2232         .into_iter()
2233         .map(|t| (t.0, db.get_storage_stat(t).unwrap()))
2234         .collect()
2235 }
2236 
assert_storage_increased( db: &mut KeystoreDB, increased_storage_types: Vec<MetricsStorage>, baseline: &mut BTreeMap<i32, StorageStats>, )2237 fn assert_storage_increased(
2238     db: &mut KeystoreDB,
2239     increased_storage_types: Vec<MetricsStorage>,
2240     baseline: &mut BTreeMap<i32, StorageStats>,
2241 ) {
2242     for storage in increased_storage_types {
2243         // Verify the expected storage increased.
2244         let new = db.get_storage_stat(storage).unwrap();
2245         let old = &baseline[&storage.0];
2246         assert!(new.size >= old.size, "{}: {} >= {}", storage.0, new.size, old.size);
2247         assert!(
2248             new.unused_size <= old.unused_size,
2249             "{}: {} <= {}",
2250             storage.0,
2251             new.unused_size,
2252             old.unused_size
2253         );
2254 
2255         // Update the baseline with the new value so that it succeeds in the
2256         // later comparison.
2257         baseline.insert(storage.0, new);
2258     }
2259 
2260     // Get an updated map of the storage and verify there were no unexpected changes.
2261     let updated_stats = get_storage_stats_map(db);
2262     assert_eq!(updated_stats.len(), baseline.len());
2263 
2264     for &k in baseline.keys() {
2265         let stringify = |map: &BTreeMap<i32, StorageStats>| -> String {
2266             let mut s = String::new();
2267             for &k in map.keys() {
2268                 writeln!(&mut s, "  {}: {}, {}", &k, map[&k].size, map[&k].unused_size)
2269                     .expect("string concat failed");
2270             }
2271             s
2272         };
2273 
2274         assert!(
2275             updated_stats[&k].size == baseline[&k].size
2276                 && updated_stats[&k].unused_size == baseline[&k].unused_size,
2277             "updated_stats:\n{}\nbaseline:\n{}",
2278             stringify(&updated_stats),
2279             stringify(baseline)
2280         );
2281     }
2282 }
2283 
2284 #[test]
test_verify_key_table_size_reporting() -> Result<()>2285 fn test_verify_key_table_size_reporting() -> Result<()> {
2286     let mut db = new_test_db()?;
2287     let mut working_stats = get_storage_stats_map(&mut db);
2288 
2289     let key_id = create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
2290     assert_storage_increased(
2291         &mut db,
2292         vec![
2293             MetricsStorage::KEY_ENTRY,
2294             MetricsStorage::KEY_ENTRY_ID_INDEX,
2295             MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
2296         ],
2297         &mut working_stats,
2298     );
2299 
2300     let mut blob_metadata = BlobMetaData::new();
2301     blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
2302     db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), None)?;
2303     assert_storage_increased(
2304         &mut db,
2305         vec![
2306             MetricsStorage::BLOB_ENTRY,
2307             MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
2308             MetricsStorage::BLOB_METADATA,
2309             MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
2310         ],
2311         &mut working_stats,
2312     );
2313 
2314     let params = make_test_params(None);
2315     db.insert_keyparameter(&key_id, &params)?;
2316     assert_storage_increased(
2317         &mut db,
2318         vec![MetricsStorage::KEY_PARAMETER, MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX],
2319         &mut working_stats,
2320     );
2321 
2322     let mut metadata = KeyMetaData::new();
2323     metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
2324     db.insert_key_metadata(&key_id, &metadata)?;
2325     assert_storage_increased(
2326         &mut db,
2327         vec![MetricsStorage::KEY_METADATA, MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX],
2328         &mut working_stats,
2329     );
2330 
2331     let mut sum = 0;
2332     for stat in working_stats.values() {
2333         sum += stat.size;
2334     }
2335     let total = db.get_storage_stat(MetricsStorage::DATABASE)?.size;
2336     assert!(sum <= total, "Expected sum <= total. sum: {}, total: {}", sum, total);
2337 
2338     Ok(())
2339 }
2340 
2341 #[test]
test_verify_auth_table_size_reporting() -> Result<()>2342 fn test_verify_auth_table_size_reporting() -> Result<()> {
2343     let mut db = new_test_db()?;
2344     let mut working_stats = get_storage_stats_map(&mut db);
2345     db.insert_auth_token(&HardwareAuthToken {
2346         challenge: 123,
2347         userId: 456,
2348         authenticatorId: 789,
2349         authenticatorType: kmhw_authenticator_type::ANY,
2350         timestamp: Timestamp { milliSeconds: 10 },
2351         mac: b"mac".to_vec(),
2352     });
2353     assert_storage_increased(&mut db, vec![MetricsStorage::AUTH_TOKEN], &mut working_stats);
2354     Ok(())
2355 }
2356 
2357 #[test]
test_verify_grant_table_size_reporting() -> Result<()>2358 fn test_verify_grant_table_size_reporting() -> Result<()> {
2359     const OWNER: i64 = 1;
2360     let mut db = new_test_db()?;
2361     make_test_key_entry(&mut db, Domain::APP, OWNER, TEST_ALIAS, None)?;
2362 
2363     let mut working_stats = get_storage_stats_map(&mut db);
2364     db.grant(
2365         &KeyDescriptor {
2366             domain: Domain::APP,
2367             nspace: 0,
2368             alias: Some(TEST_ALIAS.to_string()),
2369             blob: None,
2370         },
2371         OWNER as u32,
2372         123,
2373         key_perm_set![KeyPerm::Use],
2374         |_, _| Ok(()),
2375     )?;
2376 
2377     assert_storage_increased(&mut db, vec![MetricsStorage::GRANT], &mut working_stats);
2378 
2379     Ok(())
2380 }
2381 
2382 #[test]
find_auth_token_entry_returns_latest() -> Result<()>2383 fn find_auth_token_entry_returns_latest() -> Result<()> {
2384     let mut db = new_test_db()?;
2385     db.insert_auth_token(&HardwareAuthToken {
2386         challenge: 123,
2387         userId: 456,
2388         authenticatorId: 789,
2389         authenticatorType: kmhw_authenticator_type::ANY,
2390         timestamp: Timestamp { milliSeconds: 10 },
2391         mac: b"mac0".to_vec(),
2392     });
2393     std::thread::sleep(std::time::Duration::from_millis(1));
2394     db.insert_auth_token(&HardwareAuthToken {
2395         challenge: 123,
2396         userId: 457,
2397         authenticatorId: 789,
2398         authenticatorType: kmhw_authenticator_type::ANY,
2399         timestamp: Timestamp { milliSeconds: 12 },
2400         mac: b"mac1".to_vec(),
2401     });
2402     std::thread::sleep(std::time::Duration::from_millis(1));
2403     db.insert_auth_token(&HardwareAuthToken {
2404         challenge: 123,
2405         userId: 458,
2406         authenticatorId: 789,
2407         authenticatorType: kmhw_authenticator_type::ANY,
2408         timestamp: Timestamp { milliSeconds: 3 },
2409         mac: b"mac2".to_vec(),
2410     });
2411     // All three entries are in the database
2412     assert_eq!(db.perboot.auth_tokens_len(), 3);
2413     // It selected the most recent timestamp
2414     assert_eq!(db.find_auth_token_entry(|_| true).unwrap().auth_token.mac, b"mac2".to_vec());
2415     Ok(())
2416 }
2417 
blob_count(db: &mut KeystoreDB, sc_type: SubComponentType) -> usize2418 fn blob_count(db: &mut KeystoreDB, sc_type: SubComponentType) -> usize {
2419     db.with_transaction(TransactionBehavior::Deferred, |tx| {
2420         tx.query_row(
2421             "SELECT COUNT(*) FROM persistent.blobentry
2422                      WHERE subcomponent_type = ?;",
2423             params![sc_type],
2424             |row| row.get(0),
2425         )
2426         .context(ks_err!("Failed to count number of {sc_type:?} blobs"))
2427         .no_gc()
2428     })
2429     .unwrap()
2430 }
2431 
blob_count_in_state(db: &mut KeystoreDB, sc_type: SubComponentType, state: BlobState) -> usize2432 fn blob_count_in_state(db: &mut KeystoreDB, sc_type: SubComponentType, state: BlobState) -> usize {
2433     db.with_transaction(TransactionBehavior::Deferred, |tx| {
2434         tx.query_row(
2435             "SELECT COUNT(*) FROM persistent.blobentry
2436                      WHERE subcomponent_type = ? AND state = ?;",
2437             params![sc_type, state],
2438             |row| row.get(0),
2439         )
2440         .context(ks_err!("Failed to count number of {sc_type:?} blobs"))
2441         .no_gc()
2442     })
2443     .unwrap()
2444 }
2445 
2446 #[test]
test_blobentry_gc() -> Result<()>2447 fn test_blobentry_gc() -> Result<()> {
2448     let mut db = new_test_db()?;
2449     let _key_id1 = make_test_key_entry(&mut db, Domain::APP, 1, "key1", None)?.0;
2450     let key_guard2 = make_test_key_entry(&mut db, Domain::APP, 2, "key2", None)?;
2451     let key_guard3 = make_test_key_entry(&mut db, Domain::APP, 3, "key3", None)?;
2452     let key_id4 = make_test_key_entry(&mut db, Domain::APP, 4, "key4", None)?.0;
2453     let key_id5 = make_test_key_entry(&mut db, Domain::APP, 5, "key5", None)?.0;
2454 
2455     assert_eq!(5, blob_count(&mut db, SubComponentType::KEY_BLOB));
2456     assert_eq!(5, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2457     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2458     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2459     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2460     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2461 
2462     // Replace the keyblobs for keys 2 and 3.  The previous blobs will still exist.
2463     db.set_blob(&key_guard2, SubComponentType::KEY_BLOB, Some(&[1, 2, 3]), None)?;
2464     db.set_blob(&key_guard3, SubComponentType::KEY_BLOB, Some(&[1, 2, 3]), None)?;
2465 
2466     assert_eq!(7, blob_count(&mut db, SubComponentType::KEY_BLOB));
2467     assert_eq!(5, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2468     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2469     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2470     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2471     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2472 
2473     // Delete keys 4 and 5.  The keyblobs aren't removed yet.
2474     db.with_transaction(Immediate("TX_delete_test_keys"), |tx| {
2475         KeystoreDB::mark_unreferenced(tx, key_id4)?;
2476         KeystoreDB::mark_unreferenced(tx, key_id5)?;
2477         Ok(()).no_gc()
2478     })
2479     .unwrap();
2480 
2481     assert_eq!(7, blob_count(&mut db, SubComponentType::KEY_BLOB));
2482     assert_eq!(3, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2483     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2484     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2485     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2486     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2487 
2488     // First garbage collection should return all 4 blobentry rows that are no longer current for
2489     // their key.
2490     let superseded = db.handle_next_superseded_blobs(&[], 20).unwrap();
2491     let superseded_ids: Vec<i64> = superseded.iter().map(|v| v.blob_id).collect();
2492     assert_eq!(4, superseded.len());
2493     assert_eq!(7, blob_count(&mut db, SubComponentType::KEY_BLOB));
2494     assert_eq!(3, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2495     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2496     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2497     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2498     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2499 
2500     // Feed the superseded blob IDs back in, to trigger removal of the old KEY_BLOB entries.  As no
2501     // new superseded KEY_BLOBs are found, the unreferenced CERT/CERT_CHAIN blobs are removed.
2502     let superseded = db.handle_next_superseded_blobs(&superseded_ids, 20).unwrap();
2503     let superseded_ids: Vec<i64> = superseded.iter().map(|v| v.blob_id).collect();
2504     assert_eq!(0, superseded.len());
2505     assert_eq!(3, blob_count(&mut db, SubComponentType::KEY_BLOB));
2506     assert_eq!(3, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2507     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2508     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2509     assert_eq!(3, blob_count(&mut db, SubComponentType::CERT));
2510     assert_eq!(3, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2511 
2512     // Nothing left to garbage collect.
2513     let superseded = db.handle_next_superseded_blobs(&superseded_ids, 20).unwrap();
2514     assert_eq!(0, superseded.len());
2515     assert_eq!(3, blob_count(&mut db, SubComponentType::KEY_BLOB));
2516     assert_eq!(3, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2517     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2518     assert_eq!(0, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2519     assert_eq!(3, blob_count(&mut db, SubComponentType::CERT));
2520     assert_eq!(3, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2521 
2522     Ok(())
2523 }
2524 
2525 #[test]
test_upgrade_1_to_2() -> Result<()>2526 fn test_upgrade_1_to_2() -> Result<()> {
2527     let mut db = new_test_db()?;
2528     let _key_id1 = make_test_key_entry(&mut db, Domain::APP, 1, "key1", None)?.0;
2529     let key_guard2 = make_test_key_entry(&mut db, Domain::APP, 2, "key2", None)?;
2530     let key_guard3 = make_test_key_entry(&mut db, Domain::APP, 3, "key3", None)?;
2531     let key_id4 = make_test_key_entry(&mut db, Domain::APP, 4, "key4", None)?.0;
2532     let key_id5 = make_test_key_entry(&mut db, Domain::APP, 5, "key5", None)?.0;
2533 
2534     // Replace the keyblobs for keys 2 and 3.  The previous blobs will still exist.
2535     db.set_blob(&key_guard2, SubComponentType::KEY_BLOB, Some(&[1, 2, 3]), None)?;
2536     db.set_blob(&key_guard3, SubComponentType::KEY_BLOB, Some(&[1, 2, 3]), None)?;
2537 
2538     // Delete keys 4 and 5.  The keyblobs aren't removed yet.
2539     db.with_transaction(Immediate("TX_delete_test_keys"), |tx| {
2540         KeystoreDB::mark_unreferenced(tx, key_id4)?;
2541         KeystoreDB::mark_unreferenced(tx, key_id5)?;
2542         Ok(()).no_gc()
2543     })
2544     .unwrap();
2545     assert_eq!(7, blob_count(&mut db, SubComponentType::KEY_BLOB));
2546     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2547     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2548 
2549     // Manually downgrade the database to the v1 schema.
2550     db.with_transaction(Immediate("TX_downgrade_2_to_1"), |tx| {
2551         tx.execute("DROP INDEX persistent.keyentry_state_index;", params!())?;
2552         tx.execute("DROP INDEX persistent.blobentry_state_index;", params!())?;
2553         tx.execute("ALTER TABLE persistent.blobentry DROP COLUMN state;", params!())?;
2554         Ok(()).no_gc()
2555     })?;
2556 
2557     // Run the upgrade process.
2558     let version = db.with_transaction(Immediate("TX_upgrade_1_to_2"), |tx| {
2559         KeystoreDB::from_1_to_2(tx).no_gc()
2560     })?;
2561     assert_eq!(version, 2);
2562 
2563     // Check blobs have acquired the right `state` values.
2564     assert_eq!(7, blob_count(&mut db, SubComponentType::KEY_BLOB));
2565     assert_eq!(3, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Current));
2566     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Superseded));
2567     assert_eq!(2, blob_count_in_state(&mut db, SubComponentType::KEY_BLOB, BlobState::Orphaned));
2568     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT));
2569     assert_eq!(5, blob_count(&mut db, SubComponentType::CERT_CHAIN));
2570 
2571     Ok(())
2572 }
2573 
2574 #[test]
test_load_key_descriptor() -> Result<()>2575 fn test_load_key_descriptor() -> Result<()> {
2576     let mut db = new_test_db()?;
2577     let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)?.0;
2578 
2579     let key = db.load_key_descriptor(key_id)?.unwrap();
2580 
2581     assert_eq!(key.domain, Domain::APP);
2582     assert_eq!(key.nspace, 1);
2583     assert_eq!(key.alias, Some(TEST_ALIAS.to_string()));
2584 
2585     // No such id
2586     assert_eq!(db.load_key_descriptor(key_id + 1)?, None);
2587     Ok(())
2588 }
2589 
2590 #[test]
test_get_list_app_uids_for_sid() -> Result<()>2591 fn test_get_list_app_uids_for_sid() -> Result<()> {
2592     let uid: i32 = 1;
2593     let uid_offset: i64 = (uid as i64) * (AID_USER_OFFSET as i64);
2594     let first_sid = 667;
2595     let second_sid = 669;
2596     let first_app_id: i64 = 123 + uid_offset;
2597     let second_app_id: i64 = 456 + uid_offset;
2598     let third_app_id: i64 = 789 + uid_offset;
2599     let unrelated_app_id: i64 = 1011 + uid_offset;
2600     let mut db = new_test_db()?;
2601     make_test_key_entry_with_sids(
2602         &mut db,
2603         Domain::APP,
2604         first_app_id,
2605         TEST_ALIAS,
2606         None,
2607         &[first_sid],
2608     )
2609     .context("test_get_list_app_uids_for_sid")?;
2610     make_test_key_entry_with_sids(
2611         &mut db,
2612         Domain::APP,
2613         second_app_id,
2614         "alias2",
2615         None,
2616         &[first_sid],
2617     )
2618     .context("test_get_list_app_uids_for_sid")?;
2619     make_test_key_entry_with_sids(
2620         &mut db,
2621         Domain::APP,
2622         second_app_id,
2623         TEST_ALIAS,
2624         None,
2625         &[second_sid],
2626     )
2627     .context("test_get_list_app_uids_for_sid")?;
2628     make_test_key_entry_with_sids(
2629         &mut db,
2630         Domain::APP,
2631         third_app_id,
2632         "alias3",
2633         None,
2634         &[second_sid],
2635     )
2636     .context("test_get_list_app_uids_for_sid")?;
2637     make_test_key_entry_with_sids(&mut db, Domain::APP, unrelated_app_id, TEST_ALIAS, None, &[])
2638         .context("test_get_list_app_uids_for_sid")?;
2639 
2640     let mut first_sid_apps = db.get_app_uids_affected_by_sid(uid, first_sid)?;
2641     first_sid_apps.sort();
2642     assert_eq!(first_sid_apps, vec![first_app_id, second_app_id]);
2643     let mut second_sid_apps = db.get_app_uids_affected_by_sid(uid, second_sid)?;
2644     second_sid_apps.sort();
2645     assert_eq!(second_sid_apps, vec![second_app_id, third_app_id]);
2646     Ok(())
2647 }
2648 
2649 #[test]
test_get_list_app_uids_with_multiple_sids() -> Result<()>2650 fn test_get_list_app_uids_with_multiple_sids() -> Result<()> {
2651     let uid: i32 = 1;
2652     let uid_offset: i64 = (uid as i64) * (AID_USER_OFFSET as i64);
2653     let first_sid = 667;
2654     let second_sid = 669;
2655     let third_sid = 772;
2656     let first_app_id: i64 = 123 + uid_offset;
2657     let second_app_id: i64 = 456 + uid_offset;
2658     let mut db = new_test_db()?;
2659     make_test_key_entry_with_sids(
2660         &mut db,
2661         Domain::APP,
2662         first_app_id,
2663         TEST_ALIAS,
2664         None,
2665         &[first_sid, second_sid],
2666     )
2667     .context("test_get_list_app_uids_for_sid")?;
2668     make_test_key_entry_with_sids(
2669         &mut db,
2670         Domain::APP,
2671         second_app_id,
2672         "alias2",
2673         None,
2674         &[second_sid, third_sid],
2675     )
2676     .context("test_get_list_app_uids_for_sid")?;
2677 
2678     let first_sid_apps = db.get_app_uids_affected_by_sid(uid, first_sid)?;
2679     assert_eq!(first_sid_apps, vec![first_app_id]);
2680 
2681     let mut second_sid_apps = db.get_app_uids_affected_by_sid(uid, second_sid)?;
2682     second_sid_apps.sort();
2683     assert_eq!(second_sid_apps, vec![first_app_id, second_app_id]);
2684 
2685     let third_sid_apps = db.get_app_uids_affected_by_sid(uid, third_sid)?;
2686     assert_eq!(third_sid_apps, vec![second_app_id]);
2687     Ok(())
2688 }
2689 
2690 // Starting from `next_keyid`, add keys to the database until the count reaches
2691 // `key_count`.  (`next_keyid` is assumed to indicate how many rows already exist.)
db_populate_keys(db: &mut KeystoreDB, next_keyid: usize, key_count: usize)2692 fn db_populate_keys(db: &mut KeystoreDB, next_keyid: usize, key_count: usize) {
2693     db.with_transaction(Immediate("test_keyentry"), |tx| {
2694         for next_keyid in next_keyid..key_count {
2695             tx.execute(
2696                 "INSERT into persistent.keyentry
2697                         (id, key_type, domain, namespace, alias, state, km_uuid)
2698                         VALUES(?, ?, ?, ?, ?, ?, ?);",
2699                 params![
2700                     next_keyid,
2701                     KeyType::Client,
2702                     Domain::APP.0 as u32,
2703                     10001,
2704                     &format!("alias-{next_keyid}"),
2705                     KeyLifeCycle::Live,
2706                     KEYSTORE_UUID,
2707                 ],
2708             )?;
2709             tx.execute(
2710                 "INSERT INTO persistent.blobentry
2711                          (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);",
2712                 params![SubComponentType::KEY_BLOB, next_keyid, TEST_KEY_BLOB],
2713             )?;
2714             tx.execute(
2715                 "INSERT INTO persistent.blobentry
2716                          (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);",
2717                 params![SubComponentType::CERT, next_keyid, TEST_CERT_BLOB],
2718             )?;
2719             tx.execute(
2720                 "INSERT INTO persistent.blobentry
2721                          (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);",
2722                 params![SubComponentType::CERT_CHAIN, next_keyid, TEST_CERT_CHAIN_BLOB],
2723             )?;
2724         }
2725         Ok(()).no_gc()
2726     })
2727     .unwrap()
2728 }
2729 
2730 /// Run the provided `test_fn` against the database at various increasing stages of
2731 /// database population.
run_with_many_keys<F, T>(max_count: usize, test_fn: F) -> Result<()> where F: Fn(&mut KeystoreDB) -> T,2732 fn run_with_many_keys<F, T>(max_count: usize, test_fn: F) -> Result<()>
2733 where
2734     F: Fn(&mut KeystoreDB) -> T,
2735 {
2736     prep_and_run_with_many_keys(max_count, |_db| (), test_fn)
2737 }
2738 
2739 /// Run the provided `test_fn` against the database at various increasing stages of
2740 /// database population.
prep_and_run_with_many_keys<F, T, P>(max_count: usize, prep_fn: P, test_fn: F) -> Result<()> where F: Fn(&mut KeystoreDB) -> T, P: Fn(&mut KeystoreDB),2741 fn prep_and_run_with_many_keys<F, T, P>(max_count: usize, prep_fn: P, test_fn: F) -> Result<()>
2742 where
2743     F: Fn(&mut KeystoreDB) -> T,
2744     P: Fn(&mut KeystoreDB),
2745 {
2746     android_logger::init_once(
2747         android_logger::Config::default()
2748             .with_tag("keystore2_test")
2749             .with_max_level(log::LevelFilter::Debug),
2750     );
2751     // Put the test database on disk for a more realistic result.
2752     let db_root = tempfile::Builder::new().prefix("ks2db-test-").tempdir().unwrap();
2753     let mut db_path = db_root.path().to_owned();
2754     db_path.push("ks2-test.sqlite");
2755     let mut db = new_test_db_at(&db_path.to_string_lossy())?;
2756 
2757     println!("\nNumber_of_keys,time_in_s");
2758     let mut key_count = 10;
2759     let mut next_keyid = 0;
2760     while key_count < max_count {
2761         db_populate_keys(&mut db, next_keyid, key_count);
2762         assert_eq!(db_key_count(&mut db), key_count);
2763 
2764         // Perform any test-specific preparation
2765         prep_fn(&mut db);
2766 
2767         // Time execution of the test function.
2768         let start = std::time::Instant::now();
2769         let _result = test_fn(&mut db);
2770         println!("{key_count}, {}", start.elapsed().as_secs_f64());
2771 
2772         next_keyid = key_count;
2773         key_count *= 2;
2774     }
2775 
2776     Ok(())
2777 }
2778 
db_key_count(db: &mut KeystoreDB) -> usize2779 fn db_key_count(db: &mut KeystoreDB) -> usize {
2780     db.with_transaction(TransactionBehavior::Deferred, |tx| {
2781         tx.query_row(
2782             "SELECT COUNT(*) FROM persistent.keyentry
2783                          WHERE domain = ? AND state = ? AND key_type = ?;",
2784             params![Domain::APP.0 as u32, KeyLifeCycle::Live, KeyType::Client],
2785             |row| row.get::<usize, usize>(0),
2786         )
2787         .context(ks_err!("Failed to count number of keys."))
2788         .no_gc()
2789     })
2790     .unwrap()
2791 }
2792 
2793 #[test]
test_handle_superseded_with_many_keys() -> Result<()>2794 fn test_handle_superseded_with_many_keys() -> Result<()> {
2795     run_with_many_keys(1_000_000, |db| db.handle_next_superseded_blobs(&[], 20))
2796 }
2797 
2798 #[test]
test_get_storage_stats_with_many_keys() -> Result<()>2799 fn test_get_storage_stats_with_many_keys() -> Result<()> {
2800     use android_security_metrics::aidl::android::security::metrics::Storage::Storage as MetricsStorage;
2801     run_with_many_keys(1_000_000, |db| {
2802         db.get_storage_stat(MetricsStorage::DATABASE).unwrap();
2803         db.get_storage_stat(MetricsStorage::KEY_ENTRY).unwrap();
2804         db.get_storage_stat(MetricsStorage::KEY_ENTRY_ID_INDEX).unwrap();
2805         db.get_storage_stat(MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX).unwrap();
2806         db.get_storage_stat(MetricsStorage::BLOB_ENTRY).unwrap();
2807         db.get_storage_stat(MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX).unwrap();
2808         db.get_storage_stat(MetricsStorage::KEY_PARAMETER).unwrap();
2809         db.get_storage_stat(MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX).unwrap();
2810         db.get_storage_stat(MetricsStorage::KEY_METADATA).unwrap();
2811         db.get_storage_stat(MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX).unwrap();
2812         db.get_storage_stat(MetricsStorage::GRANT).unwrap();
2813         db.get_storage_stat(MetricsStorage::AUTH_TOKEN).unwrap();
2814         db.get_storage_stat(MetricsStorage::BLOB_METADATA).unwrap();
2815         db.get_storage_stat(MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX).unwrap();
2816     })
2817 }
2818 
2819 #[test]
test_list_keys_with_many_keys() -> Result<()>2820 fn test_list_keys_with_many_keys() -> Result<()> {
2821     run_with_many_keys(1_000_000, |db: &mut KeystoreDB| -> Result<()> {
2822         // Behave equivalently to how clients list aliases.
2823         let domain = Domain::APP;
2824         let namespace = 10001;
2825         let mut start_past: Option<String> = None;
2826         let mut count = 0;
2827         let mut batches = 0;
2828         loop {
2829             let keys = db
2830                 .list_past_alias(domain, namespace, KeyType::Client, start_past.as_deref())
2831                 .unwrap();
2832             let batch_size = crate::utils::estimate_safe_amount_to_return(
2833                 domain,
2834                 namespace,
2835                 None,
2836                 &keys,
2837                 crate::utils::RESPONSE_SIZE_LIMIT,
2838             );
2839             let batch = &keys[..batch_size];
2840             count += batch.len();
2841             match batch.last() {
2842                 Some(key) => start_past.clone_from(&key.alias),
2843                 None => {
2844                     log::info!("got {count} keys in {batches} non-empty batches");
2845                     return Ok(());
2846                 }
2847             }
2848             batches += 1;
2849         }
2850     })
2851 }
2852 
2853 #[test]
test_upgrade_1_to_2_with_many_keys() -> Result<()>2854 fn test_upgrade_1_to_2_with_many_keys() -> Result<()> {
2855     prep_and_run_with_many_keys(
2856         1_000_000,
2857         |db: &mut KeystoreDB| {
2858             // Manually downgrade the database to the v1 schema.
2859             db.with_transaction(Immediate("TX_downgrade_2_to_1"), |tx| {
2860                 tx.execute("DROP INDEX persistent.keyentry_state_index;", params!())?;
2861                 tx.execute("DROP INDEX persistent.blobentry_state_index;", params!())?;
2862                 tx.execute("ALTER TABLE persistent.blobentry DROP COLUMN state;", params!())?;
2863                 Ok(()).no_gc()
2864             })
2865             .unwrap();
2866         },
2867         |db: &mut KeystoreDB| -> Result<()> {
2868             // Run the upgrade process.
2869             db.with_transaction(Immediate("TX_upgrade_1_to_2"), |tx| {
2870                 KeystoreDB::from_1_to_2(tx).no_gc()
2871             })?;
2872             Ok(())
2873         },
2874     )
2875 }
2876