• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //! This is the Keystore 2.0 database module.
16 //! The database module provides a connection to the backing SQLite store.
17 //! We have two databases one for persistent key blob storage and one for
18 //! items that have a per boot life cycle.
19 //!
20 //! ## Persistent database
21 //! The persistent database has tables for key blobs. They are organized
22 //! as follows:
23 //! The `keyentry` table is the primary table for key entries. It is
24 //! accompanied by two tables for blobs and parameters.
25 //! Each key entry occupies exactly one row in the `keyentry` table and
26 //! zero or more rows in the tables `blobentry` and `keyparameter`.
27 //!
28 //! ## Per boot database
29 //! The per boot database stores items with a per boot lifecycle.
30 //! Currently, there is only the `grant` table in this database.
31 //! Grants are references to a key that can be used to access a key by
32 //! clients that don't own that key. Grants can only be created by the
33 //! owner of a key. And only certain components can create grants.
34 //! This is governed by SEPolicy.
35 //!
36 //! ## Access control
37 //! Some database functions that load keys or create grants perform
38 //! access control. This is because in some cases access control
39 //! can only be performed after some information about the designated
40 //! key was loaded from the database. To decouple the permission checks
41 //! from the database module these functions take permission check
42 //! callbacks.
43 
44 mod perboot;
45 pub(crate) mod utils;
46 mod versioning;
47 
48 use crate::gc::Gc;
49 use crate::globals::get_keymint_dev_by_uuid;
50 use crate::impl_metadata; // This is in db_utils.rs
51 use crate::key_parameter::{KeyParameter, Tag};
52 use crate::metrics_store::log_rkp_error_stats;
53 use crate::permission::KeyPermSet;
54 use crate::utils::{get_current_time_in_milliseconds, watchdog as wd, AID_USER_OFFSET};
55 use crate::{
56     error::{Error as KsError, ErrorCode, ResponseCode},
57     super_key::SuperKeyType,
58 };
59 use anyhow::{anyhow, Context, Result};
60 use std::{convert::TryFrom, convert::TryInto, ops::Deref, time::SystemTimeError};
61 use utils as db_utils;
62 use utils::SqlField;
63 
64 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
65     HardwareAuthToken::HardwareAuthToken,
66     HardwareAuthenticatorType::HardwareAuthenticatorType, SecurityLevel::SecurityLevel,
67 };
68 use android_system_keystore2::aidl::android::system::keystore2::{
69     Domain::Domain, KeyDescriptor::KeyDescriptor,
70 };
71 use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
72     AttestationPoolStatus::AttestationPoolStatus,
73 };
74 use android_security_metrics::aidl::android::security::metrics::{
75     StorageStats::StorageStats,
76     Storage::Storage as MetricsStorage,
77     RkpError::RkpError as MetricsRkpError,
78 };
79 
80 use keystore2_crypto::ZVec;
81 use lazy_static::lazy_static;
82 use log::error;
83 #[cfg(not(test))]
84 use rand::prelude::random;
85 use rusqlite::{
86     params, params_from_iter,
87     types::FromSql,
88     types::FromSqlResult,
89     types::ToSqlOutput,
90     types::{FromSqlError, Value, ValueRef},
91     Connection, OptionalExtension, ToSql, Transaction, TransactionBehavior, NO_PARAMS,
92 };
93 
94 use std::{
95     collections::{HashMap, HashSet},
96     path::Path,
97     sync::{Arc, Condvar, Mutex},
98     time::{Duration, SystemTime},
99 };
100 
101 #[cfg(test)]
102 use tests::random;
103 
104 impl_metadata!(
105     /// A set of metadata for key entries.
106     #[derive(Debug, Default, Eq, PartialEq)]
107     pub struct KeyMetaData;
108     /// A metadata entry for key entries.
109     #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
110     pub enum KeyMetaEntry {
111         /// Date of the creation of the key entry.
112         CreationDate(DateTime) with accessor creation_date,
113         /// Expiration date for attestation keys.
114         AttestationExpirationDate(DateTime) with accessor attestation_expiration_date,
115         /// CBOR Blob that represents a COSE_Key and associated metadata needed for remote
116         /// provisioning
117         AttestationMacedPublicKey(Vec<u8>) with accessor attestation_maced_public_key,
118         /// Vector representing the raw public key so results from the server can be matched
119         /// to the right entry
120         AttestationRawPubKey(Vec<u8>) with accessor attestation_raw_pub_key,
121         /// SEC1 public key for ECDH encryption
122         Sec1PublicKey(Vec<u8>) with accessor sec1_public_key,
123         //  --- ADD NEW META DATA FIELDS HERE ---
124         // For backwards compatibility add new entries only to
125         // end of this list and above this comment.
126     };
127 );
128 
129 impl KeyMetaData {
load_from_db(key_id: i64, tx: &Transaction) -> Result<Self>130     fn load_from_db(key_id: i64, tx: &Transaction) -> Result<Self> {
131         let mut stmt = tx
132             .prepare(
133                 "SELECT tag, data from persistent.keymetadata
134                     WHERE keyentryid = ?;",
135             )
136             .context("In KeyMetaData::load_from_db: prepare statement failed.")?;
137 
138         let mut metadata: HashMap<i64, KeyMetaEntry> = Default::default();
139 
140         let mut rows =
141             stmt.query(params![key_id]).context("In KeyMetaData::load_from_db: query failed.")?;
142         db_utils::with_rows_extract_all(&mut rows, |row| {
143             let db_tag: i64 = row.get(0).context("Failed to read tag.")?;
144             metadata.insert(
145                 db_tag,
146                 KeyMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row))
147                     .context("Failed to read KeyMetaEntry.")?,
148             );
149             Ok(())
150         })
151         .context("In KeyMetaData::load_from_db.")?;
152 
153         Ok(Self { data: metadata })
154     }
155 
store_in_db(&self, key_id: i64, tx: &Transaction) -> Result<()>156     fn store_in_db(&self, key_id: i64, tx: &Transaction) -> Result<()> {
157         let mut stmt = tx
158             .prepare(
159                 "INSERT or REPLACE INTO persistent.keymetadata (keyentryid, tag, data)
160                     VALUES (?, ?, ?);",
161             )
162             .context("In KeyMetaData::store_in_db: Failed to prepare statement.")?;
163 
164         let iter = self.data.iter();
165         for (tag, entry) in iter {
166             stmt.insert(params![key_id, tag, entry,]).with_context(|| {
167                 format!("In KeyMetaData::store_in_db: Failed to insert {:?}", entry)
168             })?;
169         }
170         Ok(())
171     }
172 }
173 
174 impl_metadata!(
175     /// A set of metadata for key blobs.
176     #[derive(Debug, Default, Eq, PartialEq)]
177     pub struct BlobMetaData;
178     /// A metadata entry for key blobs.
179     #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
180     pub enum BlobMetaEntry {
181         /// If present, indicates that the blob is encrypted with another key or a key derived
182         /// from a password.
183         EncryptedBy(EncryptedBy) with accessor encrypted_by,
184         /// If the blob is password encrypted this field is set to the
185         /// salt used for the key derivation.
186         Salt(Vec<u8>) with accessor salt,
187         /// If the blob is encrypted, this field is set to the initialization vector.
188         Iv(Vec<u8>) with accessor iv,
189         /// If the blob is encrypted, this field holds the AEAD TAG.
190         AeadTag(Vec<u8>) with accessor aead_tag,
191         /// The uuid of the owning KeyMint instance.
192         KmUuid(Uuid) with accessor km_uuid,
193         /// If the key is ECDH encrypted, this is the ephemeral public key
194         PublicKey(Vec<u8>) with accessor public_key,
195         /// If the key is encrypted with a MaxBootLevel key, this is the boot level
196         /// of that key
197         MaxBootLevel(i32) with accessor max_boot_level,
198         //  --- ADD NEW META DATA FIELDS HERE ---
199         // For backwards compatibility add new entries only to
200         // end of this list and above this comment.
201     };
202 );
203 
204 impl BlobMetaData {
load_from_db(blob_id: i64, tx: &Transaction) -> Result<Self>205     fn load_from_db(blob_id: i64, tx: &Transaction) -> Result<Self> {
206         let mut stmt = tx
207             .prepare(
208                 "SELECT tag, data from persistent.blobmetadata
209                     WHERE blobentryid = ?;",
210             )
211             .context("In BlobMetaData::load_from_db: prepare statement failed.")?;
212 
213         let mut metadata: HashMap<i64, BlobMetaEntry> = Default::default();
214 
215         let mut rows =
216             stmt.query(params![blob_id]).context("In BlobMetaData::load_from_db: query failed.")?;
217         db_utils::with_rows_extract_all(&mut rows, |row| {
218             let db_tag: i64 = row.get(0).context("Failed to read tag.")?;
219             metadata.insert(
220                 db_tag,
221                 BlobMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row))
222                     .context("Failed to read BlobMetaEntry.")?,
223             );
224             Ok(())
225         })
226         .context("In BlobMetaData::load_from_db.")?;
227 
228         Ok(Self { data: metadata })
229     }
230 
store_in_db(&self, blob_id: i64, tx: &Transaction) -> Result<()>231     fn store_in_db(&self, blob_id: i64, tx: &Transaction) -> Result<()> {
232         let mut stmt = tx
233             .prepare(
234                 "INSERT or REPLACE INTO persistent.blobmetadata (blobentryid, tag, data)
235                     VALUES (?, ?, ?);",
236             )
237             .context("In BlobMetaData::store_in_db: Failed to prepare statement.")?;
238 
239         let iter = self.data.iter();
240         for (tag, entry) in iter {
241             stmt.insert(params![blob_id, tag, entry,]).with_context(|| {
242                 format!("In BlobMetaData::store_in_db: Failed to insert {:?}", entry)
243             })?;
244         }
245         Ok(())
246     }
247 }
248 
249 /// Indicates the type of the keyentry.
250 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
251 pub enum KeyType {
252     /// This is a client key type. These keys are created or imported through the Keystore 2.0
253     /// AIDL interface android.system.keystore2.
254     Client,
255     /// This is a super key type. These keys are created by keystore itself and used to encrypt
256     /// other key blobs to provide LSKF binding.
257     Super,
258     /// This is an attestation key. These keys are created by the remote provisioning mechanism.
259     Attestation,
260 }
261 
262 impl ToSql for KeyType {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>263     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
264         Ok(ToSqlOutput::Owned(Value::Integer(match self {
265             KeyType::Client => 0,
266             KeyType::Super => 1,
267             KeyType::Attestation => 2,
268         })))
269     }
270 }
271 
272 impl FromSql for KeyType {
column_result(value: ValueRef) -> FromSqlResult<Self>273     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
274         match i64::column_result(value)? {
275             0 => Ok(KeyType::Client),
276             1 => Ok(KeyType::Super),
277             2 => Ok(KeyType::Attestation),
278             v => Err(FromSqlError::OutOfRange(v)),
279         }
280     }
281 }
282 
283 /// Uuid representation that can be stored in the database.
284 /// Right now it can only be initialized from SecurityLevel.
285 /// Once KeyMint provides a UUID type a corresponding From impl shall be added.
286 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
287 pub struct Uuid([u8; 16]);
288 
289 impl Deref for Uuid {
290     type Target = [u8; 16];
291 
deref(&self) -> &Self::Target292     fn deref(&self) -> &Self::Target {
293         &self.0
294     }
295 }
296 
297 impl From<SecurityLevel> for Uuid {
from(sec_level: SecurityLevel) -> Self298     fn from(sec_level: SecurityLevel) -> Self {
299         Self((sec_level.0 as u128).to_be_bytes())
300     }
301 }
302 
303 impl ToSql for Uuid {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>304     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
305         self.0.to_sql()
306     }
307 }
308 
309 impl FromSql for Uuid {
column_result(value: ValueRef<'_>) -> FromSqlResult<Self>310     fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
311         let blob = Vec::<u8>::column_result(value)?;
312         if blob.len() != 16 {
313             return Err(FromSqlError::OutOfRange(blob.len() as i64));
314         }
315         let mut arr = [0u8; 16];
316         arr.copy_from_slice(&blob);
317         Ok(Self(arr))
318     }
319 }
320 
321 /// Key entries that are not associated with any KeyMint instance, such as pure certificate
322 /// entries are associated with this UUID.
323 pub static KEYSTORE_UUID: Uuid = Uuid([
324     0x41, 0xe3, 0xb9, 0xce, 0x27, 0x58, 0x4e, 0x91, 0xbc, 0xfd, 0xa5, 0x5d, 0x91, 0x85, 0xab, 0x11,
325 ]);
326 
327 static EXPIRATION_BUFFER_MS: i64 = 20000;
328 
329 /// Indicates how the sensitive part of this key blob is encrypted.
330 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
331 pub enum EncryptedBy {
332     /// The keyblob is encrypted by a user password.
333     /// In the database this variant is represented as NULL.
334     Password,
335     /// The keyblob is encrypted by another key with wrapped key id.
336     /// In the database this variant is represented as non NULL value
337     /// that is convertible to i64, typically NUMERIC.
338     KeyId(i64),
339 }
340 
341 impl ToSql for EncryptedBy {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>342     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
343         match self {
344             Self::Password => Ok(ToSqlOutput::Owned(Value::Null)),
345             Self::KeyId(id) => id.to_sql(),
346         }
347     }
348 }
349 
350 impl FromSql for EncryptedBy {
column_result(value: ValueRef) -> FromSqlResult<Self>351     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
352         match value {
353             ValueRef::Null => Ok(Self::Password),
354             _ => Ok(Self::KeyId(i64::column_result(value)?)),
355         }
356     }
357 }
358 
359 /// A database representation of wall clock time. DateTime stores unix epoch time as
360 /// i64 in milliseconds.
361 #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
362 pub struct DateTime(i64);
363 
364 /// Error type returned when creating DateTime or converting it from and to
365 /// SystemTime.
366 #[derive(thiserror::Error, Debug)]
367 pub enum DateTimeError {
368     /// This is returned when SystemTime and Duration computations fail.
369     #[error(transparent)]
370     SystemTimeError(#[from] SystemTimeError),
371 
372     /// This is returned when type conversions fail.
373     #[error(transparent)]
374     TypeConversion(#[from] std::num::TryFromIntError),
375 
376     /// This is returned when checked time arithmetic failed.
377     #[error("Time arithmetic failed.")]
378     TimeArithmetic,
379 }
380 
381 impl DateTime {
382     /// Constructs a new DateTime object denoting the current time. This may fail during
383     /// conversion to unix epoch time and during conversion to the internal i64 representation.
now() -> Result<Self, DateTimeError>384     pub fn now() -> Result<Self, DateTimeError> {
385         Ok(Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?))
386     }
387 
388     /// Constructs a new DateTime object from milliseconds.
from_millis_epoch(millis: i64) -> Self389     pub fn from_millis_epoch(millis: i64) -> Self {
390         Self(millis)
391     }
392 
393     /// Returns unix epoch time in milliseconds.
to_millis_epoch(self) -> i64394     pub fn to_millis_epoch(self) -> i64 {
395         self.0
396     }
397 
398     /// Returns unix epoch time in seconds.
to_secs_epoch(self) -> i64399     pub fn to_secs_epoch(self) -> i64 {
400         self.0 / 1000
401     }
402 }
403 
404 impl ToSql for DateTime {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>405     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
406         Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
407     }
408 }
409 
410 impl FromSql for DateTime {
column_result(value: ValueRef) -> FromSqlResult<Self>411     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
412         Ok(Self(i64::column_result(value)?))
413     }
414 }
415 
416 impl TryInto<SystemTime> for DateTime {
417     type Error = DateTimeError;
418 
try_into(self) -> Result<SystemTime, Self::Error>419     fn try_into(self) -> Result<SystemTime, Self::Error> {
420         // We want to construct a SystemTime representation equivalent to self, denoting
421         // a point in time THEN, but we cannot set the time directly. We can only construct
422         // a SystemTime denoting NOW, and we can get the duration between EPOCH and NOW,
423         // and between EPOCH and THEN. With this common reference we can construct the
424         // duration between NOW and THEN which we can add to our SystemTime representation
425         // of NOW to get a SystemTime representation of THEN.
426         // Durations can only be positive, thus the if statement below.
427         let now = SystemTime::now();
428         let now_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
429         let then_epoch = Duration::from_millis(self.0.try_into()?);
430         Ok(if now_epoch > then_epoch {
431             // then = now - (now_epoch - then_epoch)
432             now_epoch
433                 .checked_sub(then_epoch)
434                 .and_then(|d| now.checked_sub(d))
435                 .ok_or(DateTimeError::TimeArithmetic)?
436         } else {
437             // then = now + (then_epoch - now_epoch)
438             then_epoch
439                 .checked_sub(now_epoch)
440                 .and_then(|d| now.checked_add(d))
441                 .ok_or(DateTimeError::TimeArithmetic)?
442         })
443     }
444 }
445 
446 impl TryFrom<SystemTime> for DateTime {
447     type Error = DateTimeError;
448 
try_from(t: SystemTime) -> Result<Self, Self::Error>449     fn try_from(t: SystemTime) -> Result<Self, Self::Error> {
450         Ok(Self(t.duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?))
451     }
452 }
453 
454 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
455 enum KeyLifeCycle {
456     /// Existing keys have a key ID but are not fully populated yet.
457     /// This is a transient state. If Keystore finds any such keys when it starts up, it must move
458     /// them to Unreferenced for garbage collection.
459     Existing,
460     /// A live key is fully populated and usable by clients.
461     Live,
462     /// An unreferenced key is scheduled for garbage collection.
463     Unreferenced,
464 }
465 
466 impl ToSql for KeyLifeCycle {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>467     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
468         match self {
469             Self::Existing => Ok(ToSqlOutput::Owned(Value::Integer(0))),
470             Self::Live => Ok(ToSqlOutput::Owned(Value::Integer(1))),
471             Self::Unreferenced => Ok(ToSqlOutput::Owned(Value::Integer(2))),
472         }
473     }
474 }
475 
476 impl FromSql for KeyLifeCycle {
column_result(value: ValueRef) -> FromSqlResult<Self>477     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
478         match i64::column_result(value)? {
479             0 => Ok(KeyLifeCycle::Existing),
480             1 => Ok(KeyLifeCycle::Live),
481             2 => Ok(KeyLifeCycle::Unreferenced),
482             v => Err(FromSqlError::OutOfRange(v)),
483         }
484     }
485 }
486 
487 /// Keys have a KeyMint blob component and optional public certificate and
488 /// certificate chain components.
489 /// KeyEntryLoadBits is a bitmap that indicates to `KeystoreDB::load_key_entry`
490 /// which components shall be loaded from the database if present.
491 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
492 pub struct KeyEntryLoadBits(u32);
493 
494 impl KeyEntryLoadBits {
495     /// Indicate to `KeystoreDB::load_key_entry` that no component shall be loaded.
496     pub const NONE: KeyEntryLoadBits = Self(0);
497     /// Indicate to `KeystoreDB::load_key_entry` that the KeyMint component shall be loaded.
498     pub const KM: KeyEntryLoadBits = Self(1);
499     /// Indicate to `KeystoreDB::load_key_entry` that the Public components shall be loaded.
500     pub const PUBLIC: KeyEntryLoadBits = Self(2);
501     /// Indicate to `KeystoreDB::load_key_entry` that both components shall be loaded.
502     pub const BOTH: KeyEntryLoadBits = Self(3);
503 
504     /// Returns true if this object indicates that the public components shall be loaded.
load_public(&self) -> bool505     pub const fn load_public(&self) -> bool {
506         self.0 & Self::PUBLIC.0 != 0
507     }
508 
509     /// Returns true if the object indicates that the KeyMint component shall be loaded.
load_km(&self) -> bool510     pub const fn load_km(&self) -> bool {
511         self.0 & Self::KM.0 != 0
512     }
513 }
514 
515 lazy_static! {
516     static ref KEY_ID_LOCK: KeyIdLockDb = KeyIdLockDb::new();
517 }
518 
519 struct KeyIdLockDb {
520     locked_keys: Mutex<HashSet<i64>>,
521     cond_var: Condvar,
522 }
523 
524 /// A locked key. While a guard exists for a given key id, the same key cannot be loaded
525 /// from the database a second time. Most functions manipulating the key blob database
526 /// require a KeyIdGuard.
527 #[derive(Debug)]
528 pub struct KeyIdGuard(i64);
529 
530 impl KeyIdLockDb {
new() -> Self531     fn new() -> Self {
532         Self { locked_keys: Mutex::new(HashSet::new()), cond_var: Condvar::new() }
533     }
534 
535     /// This function blocks until an exclusive lock for the given key entry id can
536     /// be acquired. It returns a guard object, that represents the lifecycle of the
537     /// acquired lock.
get(&self, key_id: i64) -> KeyIdGuard538     pub fn get(&self, key_id: i64) -> KeyIdGuard {
539         let mut locked_keys = self.locked_keys.lock().unwrap();
540         while locked_keys.contains(&key_id) {
541             locked_keys = self.cond_var.wait(locked_keys).unwrap();
542         }
543         locked_keys.insert(key_id);
544         KeyIdGuard(key_id)
545     }
546 
547     /// This function attempts to acquire an exclusive lock on a given key id. If the
548     /// given key id is already taken the function returns None immediately. If a lock
549     /// can be acquired this function returns a guard object, that represents the
550     /// lifecycle of the acquired lock.
try_get(&self, key_id: i64) -> Option<KeyIdGuard>551     pub fn try_get(&self, key_id: i64) -> Option<KeyIdGuard> {
552         let mut locked_keys = self.locked_keys.lock().unwrap();
553         if locked_keys.insert(key_id) {
554             Some(KeyIdGuard(key_id))
555         } else {
556             None
557         }
558     }
559 }
560 
561 impl KeyIdGuard {
562     /// Get the numeric key id of the locked key.
id(&self) -> i64563     pub fn id(&self) -> i64 {
564         self.0
565     }
566 }
567 
568 impl Drop for KeyIdGuard {
drop(&mut self)569     fn drop(&mut self) {
570         let mut locked_keys = KEY_ID_LOCK.locked_keys.lock().unwrap();
571         locked_keys.remove(&self.0);
572         drop(locked_keys);
573         KEY_ID_LOCK.cond_var.notify_all();
574     }
575 }
576 
577 /// This type represents a certificate and certificate chain entry for a key.
578 #[derive(Debug, Default)]
579 pub struct CertificateInfo {
580     cert: Option<Vec<u8>>,
581     cert_chain: Option<Vec<u8>>,
582 }
583 
584 /// This type represents a Blob with its metadata and an optional superseded blob.
585 #[derive(Debug)]
586 pub struct BlobInfo<'a> {
587     blob: &'a [u8],
588     metadata: &'a BlobMetaData,
589     /// Superseded blobs are an artifact of legacy import. In some rare occasions
590     /// the key blob needs to be upgraded during import. In that case two
591     /// blob are imported, the superseded one will have to be imported first,
592     /// so that the garbage collector can reap it.
593     superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>,
594 }
595 
596 impl<'a> BlobInfo<'a> {
597     /// Create a new instance of blob info with blob and corresponding metadata
598     /// and no superseded blob info.
new(blob: &'a [u8], metadata: &'a BlobMetaData) -> Self599     pub fn new(blob: &'a [u8], metadata: &'a BlobMetaData) -> Self {
600         Self { blob, metadata, superseded_blob: None }
601     }
602 
603     /// Create a new instance of blob info with blob and corresponding metadata
604     /// as well as superseded blob info.
new_with_superseded( blob: &'a [u8], metadata: &'a BlobMetaData, superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>, ) -> Self605     pub fn new_with_superseded(
606         blob: &'a [u8],
607         metadata: &'a BlobMetaData,
608         superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>,
609     ) -> Self {
610         Self { blob, metadata, superseded_blob }
611     }
612 }
613 
614 impl CertificateInfo {
615     /// Constructs a new CertificateInfo object from `cert` and `cert_chain`
new(cert: Option<Vec<u8>>, cert_chain: Option<Vec<u8>>) -> Self616     pub fn new(cert: Option<Vec<u8>>, cert_chain: Option<Vec<u8>>) -> Self {
617         Self { cert, cert_chain }
618     }
619 
620     /// Take the cert
take_cert(&mut self) -> Option<Vec<u8>>621     pub fn take_cert(&mut self) -> Option<Vec<u8>> {
622         self.cert.take()
623     }
624 
625     /// Take the cert chain
take_cert_chain(&mut self) -> Option<Vec<u8>>626     pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> {
627         self.cert_chain.take()
628     }
629 }
630 
631 /// This type represents a certificate chain with a private key corresponding to the leaf
632 /// certificate. TODO(jbires): This will be used in a follow-on CL, for now it's used in the tests.
633 pub struct CertificateChain {
634     /// A KM key blob
635     pub private_key: ZVec,
636     /// A batch cert for private_key
637     pub batch_cert: Vec<u8>,
638     /// A full certificate chain from root signing authority to private_key, including batch_cert
639     /// for convenience.
640     pub cert_chain: Vec<u8>,
641 }
642 
643 /// This type represents a Keystore 2.0 key entry.
644 /// An entry has a unique `id` by which it can be found in the database.
645 /// It has a security level field, key parameters, and three optional fields
646 /// for the KeyMint blob, public certificate and a public certificate chain.
647 #[derive(Debug, Default, Eq, PartialEq)]
648 pub struct KeyEntry {
649     id: i64,
650     key_blob_info: Option<(Vec<u8>, BlobMetaData)>,
651     cert: Option<Vec<u8>>,
652     cert_chain: Option<Vec<u8>>,
653     km_uuid: Uuid,
654     parameters: Vec<KeyParameter>,
655     metadata: KeyMetaData,
656     pure_cert: bool,
657 }
658 
659 impl KeyEntry {
660     /// Returns the unique id of the Key entry.
id(&self) -> i64661     pub fn id(&self) -> i64 {
662         self.id
663     }
664     /// Exposes the optional KeyMint blob.
key_blob_info(&self) -> &Option<(Vec<u8>, BlobMetaData)>665     pub fn key_blob_info(&self) -> &Option<(Vec<u8>, BlobMetaData)> {
666         &self.key_blob_info
667     }
668     /// Extracts the Optional KeyMint blob including its metadata.
take_key_blob_info(&mut self) -> Option<(Vec<u8>, BlobMetaData)>669     pub fn take_key_blob_info(&mut self) -> Option<(Vec<u8>, BlobMetaData)> {
670         self.key_blob_info.take()
671     }
672     /// Exposes the optional public certificate.
cert(&self) -> &Option<Vec<u8>>673     pub fn cert(&self) -> &Option<Vec<u8>> {
674         &self.cert
675     }
676     /// Extracts the optional public certificate.
take_cert(&mut self) -> Option<Vec<u8>>677     pub fn take_cert(&mut self) -> Option<Vec<u8>> {
678         self.cert.take()
679     }
680     /// Exposes the optional public certificate chain.
cert_chain(&self) -> &Option<Vec<u8>>681     pub fn cert_chain(&self) -> &Option<Vec<u8>> {
682         &self.cert_chain
683     }
684     /// Extracts the optional public certificate_chain.
take_cert_chain(&mut self) -> Option<Vec<u8>>685     pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> {
686         self.cert_chain.take()
687     }
688     /// Returns the uuid of the owning KeyMint instance.
km_uuid(&self) -> &Uuid689     pub fn km_uuid(&self) -> &Uuid {
690         &self.km_uuid
691     }
692     /// Exposes the key parameters of this key entry.
key_parameters(&self) -> &Vec<KeyParameter>693     pub fn key_parameters(&self) -> &Vec<KeyParameter> {
694         &self.parameters
695     }
696     /// Consumes this key entry and extracts the keyparameters from it.
into_key_parameters(self) -> Vec<KeyParameter>697     pub fn into_key_parameters(self) -> Vec<KeyParameter> {
698         self.parameters
699     }
700     /// Exposes the key metadata of this key entry.
metadata(&self) -> &KeyMetaData701     pub fn metadata(&self) -> &KeyMetaData {
702         &self.metadata
703     }
704     /// This returns true if the entry is a pure certificate entry with no
705     /// private key component.
pure_cert(&self) -> bool706     pub fn pure_cert(&self) -> bool {
707         self.pure_cert
708     }
709     /// Consumes this key entry and extracts the keyparameters and metadata from it.
into_key_parameters_and_metadata(self) -> (Vec<KeyParameter>, KeyMetaData)710     pub fn into_key_parameters_and_metadata(self) -> (Vec<KeyParameter>, KeyMetaData) {
711         (self.parameters, self.metadata)
712     }
713 }
714 
715 /// Indicates the sub component of a key entry for persistent storage.
716 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
717 pub struct SubComponentType(u32);
718 impl SubComponentType {
719     /// Persistent identifier for a key blob.
720     pub const KEY_BLOB: SubComponentType = Self(0);
721     /// Persistent identifier for a certificate blob.
722     pub const CERT: SubComponentType = Self(1);
723     /// Persistent identifier for a certificate chain blob.
724     pub const CERT_CHAIN: SubComponentType = Self(2);
725 }
726 
727 impl ToSql for SubComponentType {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>728     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
729         self.0.to_sql()
730     }
731 }
732 
733 impl FromSql for SubComponentType {
column_result(value: ValueRef) -> FromSqlResult<Self>734     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
735         Ok(Self(u32::column_result(value)?))
736     }
737 }
738 
739 /// This trait is private to the database module. It is used to convey whether or not the garbage
740 /// collector shall be invoked after a database access. All closures passed to
741 /// `KeystoreDB::with_transaction` return a tuple (bool, T) where the bool indicates if the
742 /// gc needs to be triggered. This convenience function allows to turn any anyhow::Result<T>
743 /// into anyhow::Result<(bool, T)> by simply appending one of `.do_gc(bool)`, `.no_gc()`, or
744 /// `.need_gc()`.
745 trait DoGc<T> {
do_gc(self, need_gc: bool) -> Result<(bool, T)>746     fn do_gc(self, need_gc: bool) -> Result<(bool, T)>;
747 
no_gc(self) -> Result<(bool, T)>748     fn no_gc(self) -> Result<(bool, T)>;
749 
need_gc(self) -> Result<(bool, T)>750     fn need_gc(self) -> Result<(bool, T)>;
751 }
752 
753 impl<T> DoGc<T> for Result<T> {
do_gc(self, need_gc: bool) -> Result<(bool, T)>754     fn do_gc(self, need_gc: bool) -> Result<(bool, T)> {
755         self.map(|r| (need_gc, r))
756     }
757 
no_gc(self) -> Result<(bool, T)>758     fn no_gc(self) -> Result<(bool, T)> {
759         self.do_gc(false)
760     }
761 
need_gc(self) -> Result<(bool, T)>762     fn need_gc(self) -> Result<(bool, T)> {
763         self.do_gc(true)
764     }
765 }
766 
767 /// KeystoreDB wraps a connection to an SQLite database and tracks its
768 /// ownership. It also implements all of Keystore 2.0's database functionality.
769 pub struct KeystoreDB {
770     conn: Connection,
771     gc: Option<Arc<Gc>>,
772     perboot: Arc<perboot::PerbootDB>,
773 }
774 
775 /// Database representation of the monotonic time retrieved from the system call clock_gettime with
776 /// CLOCK_MONOTONIC_RAW. Stores monotonic time as i64 in milliseconds.
777 #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
778 pub struct MonotonicRawTime(i64);
779 
780 impl MonotonicRawTime {
781     /// Constructs a new MonotonicRawTime
now() -> Self782     pub fn now() -> Self {
783         Self(get_current_time_in_milliseconds())
784     }
785 
786     /// Returns the value of MonotonicRawTime in milliseconds as i64
milliseconds(&self) -> i64787     pub fn milliseconds(&self) -> i64 {
788         self.0
789     }
790 
791     /// Returns the integer value of MonotonicRawTime as i64
seconds(&self) -> i64792     pub fn seconds(&self) -> i64 {
793         self.0 / 1000
794     }
795 
796     /// Like i64::checked_sub.
checked_sub(&self, other: &Self) -> Option<Self>797     pub fn checked_sub(&self, other: &Self) -> Option<Self> {
798         self.0.checked_sub(other.0).map(Self)
799     }
800 }
801 
802 impl ToSql for MonotonicRawTime {
to_sql(&self) -> rusqlite::Result<ToSqlOutput>803     fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
804         Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
805     }
806 }
807 
808 impl FromSql for MonotonicRawTime {
column_result(value: ValueRef) -> FromSqlResult<Self>809     fn column_result(value: ValueRef) -> FromSqlResult<Self> {
810         Ok(Self(i64::column_result(value)?))
811     }
812 }
813 
814 /// This struct encapsulates the information to be stored in the database about the auth tokens
815 /// received by keystore.
816 #[derive(Clone)]
817 pub struct AuthTokenEntry {
818     auth_token: HardwareAuthToken,
819     // Time received in milliseconds
820     time_received: MonotonicRawTime,
821 }
822 
823 impl AuthTokenEntry {
new(auth_token: HardwareAuthToken, time_received: MonotonicRawTime) -> Self824     fn new(auth_token: HardwareAuthToken, time_received: MonotonicRawTime) -> Self {
825         AuthTokenEntry { auth_token, time_received }
826     }
827 
828     /// Checks if this auth token satisfies the given authentication information.
satisfies(&self, user_secure_ids: &[i64], auth_type: HardwareAuthenticatorType) -> bool829     pub fn satisfies(&self, user_secure_ids: &[i64], auth_type: HardwareAuthenticatorType) -> bool {
830         user_secure_ids.iter().any(|&sid| {
831             (sid == self.auth_token.userId || sid == self.auth_token.authenticatorId)
832                 && (((auth_type.0 as i32) & (self.auth_token.authenticatorType.0 as i32)) != 0)
833         })
834     }
835 
836     /// Returns the auth token wrapped by the AuthTokenEntry
auth_token(&self) -> &HardwareAuthToken837     pub fn auth_token(&self) -> &HardwareAuthToken {
838         &self.auth_token
839     }
840 
841     /// Returns the auth token wrapped by the AuthTokenEntry
take_auth_token(self) -> HardwareAuthToken842     pub fn take_auth_token(self) -> HardwareAuthToken {
843         self.auth_token
844     }
845 
846     /// Returns the time that this auth token was received.
time_received(&self) -> MonotonicRawTime847     pub fn time_received(&self) -> MonotonicRawTime {
848         self.time_received
849     }
850 
851     /// Returns the challenge value of the auth token.
challenge(&self) -> i64852     pub fn challenge(&self) -> i64 {
853         self.auth_token.challenge
854     }
855 }
856 
857 /// Shared in-memory databases get destroyed as soon as the last connection to them gets closed.
858 /// This object does not allow access to the database connection. But it keeps a database
859 /// connection alive in order to keep the in memory per boot database alive.
860 pub struct PerBootDbKeepAlive(Connection);
861 
862 impl KeystoreDB {
863     const UNASSIGNED_KEY_ID: i64 = -1i64;
864     const CURRENT_DB_VERSION: u32 = 1;
865     const UPGRADERS: &'static [fn(&Transaction) -> Result<u32>] = &[Self::from_0_to_1];
866 
867     /// Name of the file that holds the cross-boot persistent database.
868     pub const PERSISTENT_DB_FILENAME: &'static str = "persistent.sqlite";
869 
870     /// This will create a new database connection connecting the two
871     /// files persistent.sqlite and perboot.sqlite in the given directory.
872     /// It also attempts to initialize all of the tables.
873     /// KeystoreDB cannot be used by multiple threads.
874     /// Each thread should open their own connection using `thread_local!`.
new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self>875     pub fn new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self> {
876         let _wp = wd::watch_millis("KeystoreDB::new", 500);
877 
878         let persistent_path = Self::make_persistent_path(db_root)?;
879         let conn = Self::make_connection(&persistent_path)?;
880 
881         let mut db = Self { conn, gc, perboot: perboot::PERBOOT_DB.clone() };
882         db.with_transaction(TransactionBehavior::Immediate, |tx| {
883             versioning::upgrade_database(tx, Self::CURRENT_DB_VERSION, Self::UPGRADERS)
884                 .context("In KeystoreDB::new: trying to upgrade database.")?;
885             Self::init_tables(tx).context("Trying to initialize tables.").no_gc()
886         })?;
887         Ok(db)
888     }
889 
890     // This upgrade function deletes all MAX_BOOT_LEVEL keys, that were generated before
891     // cryptographic binding to the boot level keys was implemented.
from_0_to_1(tx: &Transaction) -> Result<u32>892     fn from_0_to_1(tx: &Transaction) -> Result<u32> {
893         tx.execute(
894             "UPDATE persistent.keyentry SET state = ?
895              WHERE
896                  id IN (SELECT keyentryid FROM persistent.keyparameter WHERE tag = ?)
897              AND
898                  id NOT IN (
899                      SELECT keyentryid FROM persistent.blobentry
900                      WHERE id IN (
901                          SELECT blobentryid FROM persistent.blobmetadata WHERE tag = ?
902                      )
903                  );",
904             params![KeyLifeCycle::Unreferenced, Tag::MAX_BOOT_LEVEL.0, BlobMetaData::MaxBootLevel],
905         )
906         .context("In from_0_to_1: Failed to delete logical boot level keys.")?;
907         Ok(1)
908     }
909 
init_tables(tx: &Transaction) -> Result<()>910     fn init_tables(tx: &Transaction) -> Result<()> {
911         tx.execute(
912             "CREATE TABLE IF NOT EXISTS persistent.keyentry (
913                      id INTEGER UNIQUE,
914                      key_type INTEGER,
915                      domain INTEGER,
916                      namespace INTEGER,
917                      alias BLOB,
918                      state INTEGER,
919                      km_uuid BLOB);",
920             NO_PARAMS,
921         )
922         .context("Failed to initialize \"keyentry\" table.")?;
923 
924         tx.execute(
925             "CREATE INDEX IF NOT EXISTS persistent.keyentry_id_index
926             ON keyentry(id);",
927             NO_PARAMS,
928         )
929         .context("Failed to create index keyentry_id_index.")?;
930 
931         tx.execute(
932             "CREATE INDEX IF NOT EXISTS persistent.keyentry_domain_namespace_index
933             ON keyentry(domain, namespace, alias);",
934             NO_PARAMS,
935         )
936         .context("Failed to create index keyentry_domain_namespace_index.")?;
937 
938         tx.execute(
939             "CREATE TABLE IF NOT EXISTS persistent.blobentry (
940                     id INTEGER PRIMARY KEY,
941                     subcomponent_type INTEGER,
942                     keyentryid INTEGER,
943                     blob BLOB);",
944             NO_PARAMS,
945         )
946         .context("Failed to initialize \"blobentry\" table.")?;
947 
948         tx.execute(
949             "CREATE INDEX IF NOT EXISTS persistent.blobentry_keyentryid_index
950             ON blobentry(keyentryid);",
951             NO_PARAMS,
952         )
953         .context("Failed to create index blobentry_keyentryid_index.")?;
954 
955         tx.execute(
956             "CREATE TABLE IF NOT EXISTS persistent.blobmetadata (
957                      id INTEGER PRIMARY KEY,
958                      blobentryid INTEGER,
959                      tag INTEGER,
960                      data ANY,
961                      UNIQUE (blobentryid, tag));",
962             NO_PARAMS,
963         )
964         .context("Failed to initialize \"blobmetadata\" table.")?;
965 
966         tx.execute(
967             "CREATE INDEX IF NOT EXISTS persistent.blobmetadata_blobentryid_index
968             ON blobmetadata(blobentryid);",
969             NO_PARAMS,
970         )
971         .context("Failed to create index blobmetadata_blobentryid_index.")?;
972 
973         tx.execute(
974             "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
975                      keyentryid INTEGER,
976                      tag INTEGER,
977                      data ANY,
978                      security_level INTEGER);",
979             NO_PARAMS,
980         )
981         .context("Failed to initialize \"keyparameter\" table.")?;
982 
983         tx.execute(
984             "CREATE INDEX IF NOT EXISTS persistent.keyparameter_keyentryid_index
985             ON keyparameter(keyentryid);",
986             NO_PARAMS,
987         )
988         .context("Failed to create index keyparameter_keyentryid_index.")?;
989 
990         tx.execute(
991             "CREATE TABLE IF NOT EXISTS persistent.keymetadata (
992                      keyentryid INTEGER,
993                      tag INTEGER,
994                      data ANY,
995                      UNIQUE (keyentryid, tag));",
996             NO_PARAMS,
997         )
998         .context("Failed to initialize \"keymetadata\" table.")?;
999 
1000         tx.execute(
1001             "CREATE INDEX IF NOT EXISTS persistent.keymetadata_keyentryid_index
1002             ON keymetadata(keyentryid);",
1003             NO_PARAMS,
1004         )
1005         .context("Failed to create index keymetadata_keyentryid_index.")?;
1006 
1007         tx.execute(
1008             "CREATE TABLE IF NOT EXISTS persistent.grant (
1009                     id INTEGER UNIQUE,
1010                     grantee INTEGER,
1011                     keyentryid INTEGER,
1012                     access_vector INTEGER);",
1013             NO_PARAMS,
1014         )
1015         .context("Failed to initialize \"grant\" table.")?;
1016 
1017         Ok(())
1018     }
1019 
make_persistent_path(db_root: &Path) -> Result<String>1020     fn make_persistent_path(db_root: &Path) -> Result<String> {
1021         // Build the path to the sqlite file.
1022         let mut persistent_path = db_root.to_path_buf();
1023         persistent_path.push(Self::PERSISTENT_DB_FILENAME);
1024 
1025         // Now convert them to strings prefixed with "file:"
1026         let mut persistent_path_str = "file:".to_owned();
1027         persistent_path_str.push_str(&persistent_path.to_string_lossy());
1028 
1029         Ok(persistent_path_str)
1030     }
1031 
make_connection(persistent_file: &str) -> Result<Connection>1032     fn make_connection(persistent_file: &str) -> Result<Connection> {
1033         let conn =
1034             Connection::open_in_memory().context("Failed to initialize SQLite connection.")?;
1035 
1036         loop {
1037             if let Err(e) = conn
1038                 .execute("ATTACH DATABASE ? as persistent;", params![persistent_file])
1039                 .context("Failed to attach database persistent.")
1040             {
1041                 if Self::is_locked_error(&e) {
1042                     std::thread::sleep(std::time::Duration::from_micros(500));
1043                     continue;
1044                 } else {
1045                     return Err(e);
1046                 }
1047             }
1048             break;
1049         }
1050 
1051         // Drop the cache size from default (2M) to 0.5M
1052         conn.execute("PRAGMA persistent.cache_size = -500;", params![])
1053             .context("Failed to decrease cache size for persistent db")?;
1054 
1055         Ok(conn)
1056     }
1057 
do_table_size_query( &mut self, storage_type: MetricsStorage, query: &str, params: &[&str], ) -> Result<StorageStats>1058     fn do_table_size_query(
1059         &mut self,
1060         storage_type: MetricsStorage,
1061         query: &str,
1062         params: &[&str],
1063     ) -> Result<StorageStats> {
1064         let (total, unused) = self.with_transaction(TransactionBehavior::Deferred, |tx| {
1065             tx.query_row(query, params_from_iter(params), |row| Ok((row.get(0)?, row.get(1)?)))
1066                 .with_context(|| {
1067                     format!("get_storage_stat: Error size of storage type {}", storage_type.0)
1068                 })
1069                 .no_gc()
1070         })?;
1071         Ok(StorageStats { storage_type, size: total, unused_size: unused })
1072     }
1073 
get_total_size(&mut self) -> Result<StorageStats>1074     fn get_total_size(&mut self) -> Result<StorageStats> {
1075         self.do_table_size_query(
1076             MetricsStorage::DATABASE,
1077             "SELECT page_count * page_size, freelist_count * page_size
1078              FROM pragma_page_count('persistent'),
1079                   pragma_page_size('persistent'),
1080                   persistent.pragma_freelist_count();",
1081             &[],
1082         )
1083     }
1084 
get_table_size( &mut self, storage_type: MetricsStorage, schema: &str, table: &str, ) -> Result<StorageStats>1085     fn get_table_size(
1086         &mut self,
1087         storage_type: MetricsStorage,
1088         schema: &str,
1089         table: &str,
1090     ) -> Result<StorageStats> {
1091         self.do_table_size_query(
1092             storage_type,
1093             "SELECT pgsize,unused FROM dbstat(?1)
1094              WHERE name=?2 AND aggregate=TRUE;",
1095             &[schema, table],
1096         )
1097     }
1098 
1099     /// Fetches a storage statisitics atom for a given storage type. For storage
1100     /// types that map to a table, information about the table's storage is
1101     /// returned. Requests for storage types that are not DB tables return None.
get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats>1102     pub fn get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats> {
1103         let _wp = wd::watch_millis("KeystoreDB::get_storage_stat", 500);
1104 
1105         match storage_type {
1106             MetricsStorage::DATABASE => self.get_total_size(),
1107             MetricsStorage::KEY_ENTRY => {
1108                 self.get_table_size(storage_type, "persistent", "keyentry")
1109             }
1110             MetricsStorage::KEY_ENTRY_ID_INDEX => {
1111                 self.get_table_size(storage_type, "persistent", "keyentry_id_index")
1112             }
1113             MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX => {
1114                 self.get_table_size(storage_type, "persistent", "keyentry_domain_namespace_index")
1115             }
1116             MetricsStorage::BLOB_ENTRY => {
1117                 self.get_table_size(storage_type, "persistent", "blobentry")
1118             }
1119             MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX => {
1120                 self.get_table_size(storage_type, "persistent", "blobentry_keyentryid_index")
1121             }
1122             MetricsStorage::KEY_PARAMETER => {
1123                 self.get_table_size(storage_type, "persistent", "keyparameter")
1124             }
1125             MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX => {
1126                 self.get_table_size(storage_type, "persistent", "keyparameter_keyentryid_index")
1127             }
1128             MetricsStorage::KEY_METADATA => {
1129                 self.get_table_size(storage_type, "persistent", "keymetadata")
1130             }
1131             MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX => {
1132                 self.get_table_size(storage_type, "persistent", "keymetadata_keyentryid_index")
1133             }
1134             MetricsStorage::GRANT => self.get_table_size(storage_type, "persistent", "grant"),
1135             MetricsStorage::AUTH_TOKEN => {
1136                 // Since the table is actually a BTreeMap now, unused_size is not meaningfully
1137                 // reportable
1138                 // Size provided is only an approximation
1139                 Ok(StorageStats {
1140                     storage_type,
1141                     size: (self.perboot.auth_tokens_len() * std::mem::size_of::<AuthTokenEntry>())
1142                         as i32,
1143                     unused_size: 0,
1144                 })
1145             }
1146             MetricsStorage::BLOB_METADATA => {
1147                 self.get_table_size(storage_type, "persistent", "blobmetadata")
1148             }
1149             MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX => {
1150                 self.get_table_size(storage_type, "persistent", "blobmetadata_blobentryid_index")
1151             }
1152             _ => Err(anyhow::Error::msg(format!("Unsupported storage type: {}", storage_type.0))),
1153         }
1154     }
1155 
1156     /// This function is intended to be used by the garbage collector.
1157     /// It deletes the blobs given by `blob_ids_to_delete`. It then tries to find up to `max_blobs`
1158     /// superseded key blobs that might need special handling by the garbage collector.
1159     /// If no further superseded blobs can be found it deletes all other superseded blobs that don't
1160     /// need special handling and returns None.
handle_next_superseded_blobs( &mut self, blob_ids_to_delete: &[i64], max_blobs: usize, ) -> Result<Vec<(i64, Vec<u8>, BlobMetaData)>>1161     pub fn handle_next_superseded_blobs(
1162         &mut self,
1163         blob_ids_to_delete: &[i64],
1164         max_blobs: usize,
1165     ) -> Result<Vec<(i64, Vec<u8>, BlobMetaData)>> {
1166         let _wp = wd::watch_millis("KeystoreDB::handle_next_superseded_blob", 500);
1167         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1168             // Delete the given blobs.
1169             for blob_id in blob_ids_to_delete {
1170                 tx.execute(
1171                     "DELETE FROM persistent.blobmetadata WHERE blobentryid = ?;",
1172                     params![blob_id],
1173                 )
1174                 .context("Trying to delete blob metadata.")?;
1175                 tx.execute("DELETE FROM persistent.blobentry WHERE id = ?;", params![blob_id])
1176                     .context("Trying to blob.")?;
1177             }
1178 
1179             Self::cleanup_unreferenced(tx).context("Trying to cleanup unreferenced.")?;
1180 
1181             // Find up to max_blobx more superseded key blobs, load their metadata and return it.
1182             let result: Vec<(i64, Vec<u8>)> = {
1183                 let mut stmt = tx
1184                     .prepare(
1185                         "SELECT id, blob FROM persistent.blobentry
1186                         WHERE subcomponent_type = ?
1187                         AND (
1188                             id NOT IN (
1189                                 SELECT MAX(id) FROM persistent.blobentry
1190                                 WHERE subcomponent_type = ?
1191                                 GROUP BY keyentryid, subcomponent_type
1192                             )
1193                         OR keyentryid NOT IN (SELECT id FROM persistent.keyentry)
1194                     ) LIMIT ?;",
1195                     )
1196                     .context("Trying to prepare query for superseded blobs.")?;
1197 
1198                 let rows = stmt
1199                     .query_map(
1200                         params![
1201                             SubComponentType::KEY_BLOB,
1202                             SubComponentType::KEY_BLOB,
1203                             max_blobs as i64,
1204                         ],
1205                         |row| Ok((row.get(0)?, row.get(1)?)),
1206                     )
1207                     .context("Trying to query superseded blob.")?;
1208 
1209                 rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>()
1210                     .context("Trying to extract superseded blobs.")?
1211             };
1212 
1213             let result = result
1214                 .into_iter()
1215                 .map(|(blob_id, blob)| {
1216                     Ok((blob_id, blob, BlobMetaData::load_from_db(blob_id, tx)?))
1217                 })
1218                 .collect::<Result<Vec<(i64, Vec<u8>, BlobMetaData)>>>()
1219                 .context("Trying to load blob metadata.")?;
1220             if !result.is_empty() {
1221                 return Ok(result).no_gc();
1222             }
1223 
1224             // We did not find any superseded key blob, so let's remove other superseded blob in
1225             // one transaction.
1226             tx.execute(
1227                 "DELETE FROM persistent.blobentry
1228                  WHERE NOT subcomponent_type = ?
1229                  AND (
1230                      id NOT IN (
1231                         SELECT MAX(id) FROM persistent.blobentry
1232                         WHERE NOT subcomponent_type = ?
1233                         GROUP BY keyentryid, subcomponent_type
1234                      ) OR keyentryid NOT IN (SELECT id FROM persistent.keyentry)
1235                  );",
1236                 params![SubComponentType::KEY_BLOB, SubComponentType::KEY_BLOB],
1237             )
1238             .context("Trying to purge superseded blobs.")?;
1239 
1240             Ok(vec![]).no_gc()
1241         })
1242         .context("In handle_next_superseded_blobs.")
1243     }
1244 
1245     /// This maintenance function should be called only once before the database is used for the
1246     /// first time. It restores the invariant that `KeyLifeCycle::Existing` is a transient state.
1247     /// The function transitions all key entries from Existing to Unreferenced unconditionally and
1248     /// returns the number of rows affected. If this returns a value greater than 0, it means that
1249     /// Keystore crashed at some point during key generation. Callers may want to log such
1250     /// occurrences.
1251     /// Unlike with `mark_unreferenced`, we don't need to purge grants, because only keys that made
1252     /// it to `KeyLifeCycle::Live` may have grants.
cleanup_leftovers(&mut self) -> Result<usize>1253     pub fn cleanup_leftovers(&mut self) -> Result<usize> {
1254         let _wp = wd::watch_millis("KeystoreDB::cleanup_leftovers", 500);
1255 
1256         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1257             tx.execute(
1258                 "UPDATE persistent.keyentry SET state = ? WHERE state = ?;",
1259                 params![KeyLifeCycle::Unreferenced, KeyLifeCycle::Existing],
1260             )
1261             .context("Failed to execute query.")
1262             .need_gc()
1263         })
1264         .context("In cleanup_leftovers.")
1265     }
1266 
1267     /// Checks if a key exists with given key type and key descriptor properties.
key_exists( &mut self, domain: Domain, nspace: i64, alias: &str, key_type: KeyType, ) -> Result<bool>1268     pub fn key_exists(
1269         &mut self,
1270         domain: Domain,
1271         nspace: i64,
1272         alias: &str,
1273         key_type: KeyType,
1274     ) -> Result<bool> {
1275         let _wp = wd::watch_millis("KeystoreDB::key_exists", 500);
1276 
1277         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1278             let key_descriptor =
1279                 KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None };
1280             let result = Self::load_key_entry_id(tx, &key_descriptor, key_type);
1281             match result {
1282                 Ok(_) => Ok(true),
1283                 Err(error) => match error.root_cause().downcast_ref::<KsError>() {
1284                     Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(false),
1285                     _ => Err(error).context("In key_exists: Failed to find if the key exists."),
1286                 },
1287             }
1288             .no_gc()
1289         })
1290         .context("In key_exists.")
1291     }
1292 
1293     /// Stores a super key in the database.
store_super_key( &mut self, user_id: u32, key_type: &SuperKeyType, blob: &[u8], blob_metadata: &BlobMetaData, key_metadata: &KeyMetaData, ) -> Result<KeyEntry>1294     pub fn store_super_key(
1295         &mut self,
1296         user_id: u32,
1297         key_type: &SuperKeyType,
1298         blob: &[u8],
1299         blob_metadata: &BlobMetaData,
1300         key_metadata: &KeyMetaData,
1301     ) -> Result<KeyEntry> {
1302         let _wp = wd::watch_millis("KeystoreDB::store_super_key", 500);
1303 
1304         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1305             let key_id = Self::insert_with_retry(|id| {
1306                 tx.execute(
1307                     "INSERT into persistent.keyentry
1308                             (id, key_type, domain, namespace, alias, state, km_uuid)
1309                             VALUES(?, ?, ?, ?, ?, ?, ?);",
1310                     params![
1311                         id,
1312                         KeyType::Super,
1313                         Domain::APP.0,
1314                         user_id as i64,
1315                         key_type.alias,
1316                         KeyLifeCycle::Live,
1317                         &KEYSTORE_UUID,
1318                     ],
1319                 )
1320             })
1321             .context("Failed to insert into keyentry table.")?;
1322 
1323             key_metadata.store_in_db(key_id, tx).context("KeyMetaData::store_in_db failed")?;
1324 
1325             Self::set_blob_internal(
1326                 tx,
1327                 key_id,
1328                 SubComponentType::KEY_BLOB,
1329                 Some(blob),
1330                 Some(blob_metadata),
1331             )
1332             .context("Failed to store key blob.")?;
1333 
1334             Self::load_key_components(tx, KeyEntryLoadBits::KM, key_id)
1335                 .context("Trying to load key components.")
1336                 .no_gc()
1337         })
1338         .context("In store_super_key.")
1339     }
1340 
1341     /// Loads super key of a given user, if exists
load_super_key( &mut self, key_type: &SuperKeyType, user_id: u32, ) -> Result<Option<(KeyIdGuard, KeyEntry)>>1342     pub fn load_super_key(
1343         &mut self,
1344         key_type: &SuperKeyType,
1345         user_id: u32,
1346     ) -> Result<Option<(KeyIdGuard, KeyEntry)>> {
1347         let _wp = wd::watch_millis("KeystoreDB::load_super_key", 500);
1348 
1349         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1350             let key_descriptor = KeyDescriptor {
1351                 domain: Domain::APP,
1352                 nspace: user_id as i64,
1353                 alias: Some(key_type.alias.into()),
1354                 blob: None,
1355             };
1356             let id = Self::load_key_entry_id(tx, &key_descriptor, KeyType::Super);
1357             match id {
1358                 Ok(id) => {
1359                     let key_entry = Self::load_key_components(tx, KeyEntryLoadBits::KM, id)
1360                         .context("In load_super_key. Failed to load key entry.")?;
1361                     Ok(Some((KEY_ID_LOCK.get(id), key_entry)))
1362                 }
1363                 Err(error) => match error.root_cause().downcast_ref::<KsError>() {
1364                     Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
1365                     _ => Err(error).context("In load_super_key."),
1366                 },
1367             }
1368             .no_gc()
1369         })
1370         .context("In load_super_key.")
1371     }
1372 
1373     /// Atomically loads a key entry and associated metadata or creates it using the
1374     /// callback create_new_key callback. The callback is called during a database
1375     /// transaction. This means that implementers should be mindful about using
1376     /// blocking operations such as IPC or grabbing mutexes.
get_or_create_key_with<F>( &mut self, domain: Domain, namespace: i64, alias: &str, km_uuid: Uuid, create_new_key: F, ) -> Result<(KeyIdGuard, KeyEntry)> where F: Fn() -> Result<(Vec<u8>, BlobMetaData)>,1377     pub fn get_or_create_key_with<F>(
1378         &mut self,
1379         domain: Domain,
1380         namespace: i64,
1381         alias: &str,
1382         km_uuid: Uuid,
1383         create_new_key: F,
1384     ) -> Result<(KeyIdGuard, KeyEntry)>
1385     where
1386         F: Fn() -> Result<(Vec<u8>, BlobMetaData)>,
1387     {
1388         let _wp = wd::watch_millis("KeystoreDB::get_or_create_key_with", 500);
1389 
1390         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1391             let id = {
1392                 let mut stmt = tx
1393                     .prepare(
1394                         "SELECT id FROM persistent.keyentry
1395                     WHERE
1396                     key_type = ?
1397                     AND domain = ?
1398                     AND namespace = ?
1399                     AND alias = ?
1400                     AND state = ?;",
1401                     )
1402                     .context("In get_or_create_key_with: Failed to select from keyentry table.")?;
1403                 let mut rows = stmt
1404                     .query(params![KeyType::Super, domain.0, namespace, alias, KeyLifeCycle::Live])
1405                     .context("In get_or_create_key_with: Failed to query from keyentry table.")?;
1406 
1407                 db_utils::with_rows_extract_one(&mut rows, |row| {
1408                     Ok(match row {
1409                         Some(r) => r.get(0).context("Failed to unpack id.")?,
1410                         None => None,
1411                     })
1412                 })
1413                 .context("In get_or_create_key_with.")?
1414             };
1415 
1416             let (id, entry) = match id {
1417                 Some(id) => (
1418                     id,
1419                     Self::load_key_components(tx, KeyEntryLoadBits::KM, id)
1420                         .context("In get_or_create_key_with.")?,
1421                 ),
1422 
1423                 None => {
1424                     let id = Self::insert_with_retry(|id| {
1425                         tx.execute(
1426                             "INSERT into persistent.keyentry
1427                         (id, key_type, domain, namespace, alias, state, km_uuid)
1428                         VALUES(?, ?, ?, ?, ?, ?, ?);",
1429                             params![
1430                                 id,
1431                                 KeyType::Super,
1432                                 domain.0,
1433                                 namespace,
1434                                 alias,
1435                                 KeyLifeCycle::Live,
1436                                 km_uuid,
1437                             ],
1438                         )
1439                     })
1440                     .context("In get_or_create_key_with.")?;
1441 
1442                     let (blob, metadata) =
1443                         create_new_key().context("In get_or_create_key_with.")?;
1444                     Self::set_blob_internal(
1445                         tx,
1446                         id,
1447                         SubComponentType::KEY_BLOB,
1448                         Some(&blob),
1449                         Some(&metadata),
1450                     )
1451                     .context("In get_or_create_key_with.")?;
1452                     (
1453                         id,
1454                         KeyEntry {
1455                             id,
1456                             key_blob_info: Some((blob, metadata)),
1457                             pure_cert: false,
1458                             ..Default::default()
1459                         },
1460                     )
1461                 }
1462             };
1463             Ok((KEY_ID_LOCK.get(id), entry)).no_gc()
1464         })
1465         .context("In get_or_create_key_with.")
1466     }
1467 
1468     /// Creates a transaction with the given behavior and executes f with the new transaction.
1469     /// The transaction is committed only if f returns Ok and retried if DatabaseBusy
1470     /// or DatabaseLocked is encountered.
with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T> where F: Fn(&Transaction) -> Result<(bool, T)>,1471     fn with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T>
1472     where
1473         F: Fn(&Transaction) -> Result<(bool, T)>,
1474     {
1475         loop {
1476             match self
1477                 .conn
1478                 .transaction_with_behavior(behavior)
1479                 .context("In with_transaction.")
1480                 .and_then(|tx| f(&tx).map(|result| (result, tx)))
1481                 .and_then(|(result, tx)| {
1482                     tx.commit().context("In with_transaction: Failed to commit transaction.")?;
1483                     Ok(result)
1484                 }) {
1485                 Ok(result) => break Ok(result),
1486                 Err(e) => {
1487                     if Self::is_locked_error(&e) {
1488                         std::thread::sleep(std::time::Duration::from_micros(500));
1489                         continue;
1490                     } else {
1491                         return Err(e).context("In with_transaction.");
1492                     }
1493                 }
1494             }
1495         }
1496         .map(|(need_gc, result)| {
1497             if need_gc {
1498                 if let Some(ref gc) = self.gc {
1499                     gc.notify_gc();
1500                 }
1501             }
1502             result
1503         })
1504     }
1505 
is_locked_error(e: &anyhow::Error) -> bool1506     fn is_locked_error(e: &anyhow::Error) -> bool {
1507         matches!(
1508             e.root_cause().downcast_ref::<rusqlite::ffi::Error>(),
1509             Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. })
1510                 | Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseLocked, .. })
1511         )
1512     }
1513 
1514     /// Creates a new key entry and allocates a new randomized id for the new key.
1515     /// The key id gets associated with a domain and namespace but not with an alias.
1516     /// To complete key generation `rebind_alias` should be called after all of the
1517     /// key artifacts, i.e., blobs and parameters have been associated with the new
1518     /// key id. Finalizing with `rebind_alias` makes the creation of a new key entry
1519     /// atomic even if key generation is not.
create_key_entry( &mut self, domain: &Domain, namespace: &i64, key_type: KeyType, km_uuid: &Uuid, ) -> Result<KeyIdGuard>1520     pub fn create_key_entry(
1521         &mut self,
1522         domain: &Domain,
1523         namespace: &i64,
1524         key_type: KeyType,
1525         km_uuid: &Uuid,
1526     ) -> Result<KeyIdGuard> {
1527         let _wp = wd::watch_millis("KeystoreDB::create_key_entry", 500);
1528 
1529         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1530             Self::create_key_entry_internal(tx, domain, namespace, key_type, km_uuid).no_gc()
1531         })
1532         .context("In create_key_entry.")
1533     }
1534 
create_key_entry_internal( tx: &Transaction, domain: &Domain, namespace: &i64, key_type: KeyType, km_uuid: &Uuid, ) -> Result<KeyIdGuard>1535     fn create_key_entry_internal(
1536         tx: &Transaction,
1537         domain: &Domain,
1538         namespace: &i64,
1539         key_type: KeyType,
1540         km_uuid: &Uuid,
1541     ) -> Result<KeyIdGuard> {
1542         match *domain {
1543             Domain::APP | Domain::SELINUX => {}
1544             _ => {
1545                 return Err(KsError::sys())
1546                     .context(format!("Domain {:?} must be either App or SELinux.", domain));
1547             }
1548         }
1549         Ok(KEY_ID_LOCK.get(
1550             Self::insert_with_retry(|id| {
1551                 tx.execute(
1552                     "INSERT into persistent.keyentry
1553                      (id, key_type, domain, namespace, alias, state, km_uuid)
1554                      VALUES(?, ?, ?, ?, NULL, ?, ?);",
1555                     params![
1556                         id,
1557                         key_type,
1558                         domain.0 as u32,
1559                         *namespace,
1560                         KeyLifeCycle::Existing,
1561                         km_uuid,
1562                     ],
1563                 )
1564             })
1565             .context("In create_key_entry_internal")?,
1566         ))
1567     }
1568 
1569     /// Creates a new attestation key entry and allocates a new randomized id for the new key.
1570     /// The key id gets associated with a domain and namespace later but not with an alias. The
1571     /// alias will be used to denote if a key has been signed as each key can only be bound to one
1572     /// domain and namespace pairing so there is no need to use them as a value for indexing into
1573     /// a key.
create_attestation_key_entry( &mut self, maced_public_key: &[u8], raw_public_key: &[u8], private_key: &[u8], km_uuid: &Uuid, ) -> Result<()>1574     pub fn create_attestation_key_entry(
1575         &mut self,
1576         maced_public_key: &[u8],
1577         raw_public_key: &[u8],
1578         private_key: &[u8],
1579         km_uuid: &Uuid,
1580     ) -> Result<()> {
1581         let _wp = wd::watch_millis("KeystoreDB::create_attestation_key_entry", 500);
1582 
1583         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1584             let key_id = KEY_ID_LOCK.get(
1585                 Self::insert_with_retry(|id| {
1586                     tx.execute(
1587                         "INSERT into persistent.keyentry
1588                             (id, key_type, domain, namespace, alias, state, km_uuid)
1589                             VALUES(?, ?, NULL, NULL, NULL, ?, ?);",
1590                         params![id, KeyType::Attestation, KeyLifeCycle::Live, km_uuid],
1591                     )
1592                 })
1593                 .context("In create_key_entry")?,
1594             );
1595             Self::set_blob_internal(
1596                 tx,
1597                 key_id.0,
1598                 SubComponentType::KEY_BLOB,
1599                 Some(private_key),
1600                 None,
1601             )?;
1602             let mut metadata = KeyMetaData::new();
1603             metadata.add(KeyMetaEntry::AttestationMacedPublicKey(maced_public_key.to_vec()));
1604             metadata.add(KeyMetaEntry::AttestationRawPubKey(raw_public_key.to_vec()));
1605             metadata.store_in_db(key_id.0, tx)?;
1606             Ok(()).no_gc()
1607         })
1608         .context("In create_attestation_key_entry")
1609     }
1610 
1611     /// Set a new blob and associates it with the given key id. Each blob
1612     /// has a sub component type.
1613     /// Each key can have one of each sub component type associated. If more
1614     /// are added only the most recent can be retrieved, and superseded blobs
1615     /// will get garbage collected.
1616     /// Components SubComponentType::CERT and SubComponentType::CERT_CHAIN can be
1617     /// removed by setting blob to None.
set_blob( &mut self, key_id: &KeyIdGuard, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1618     pub fn set_blob(
1619         &mut self,
1620         key_id: &KeyIdGuard,
1621         sc_type: SubComponentType,
1622         blob: Option<&[u8]>,
1623         blob_metadata: Option<&BlobMetaData>,
1624     ) -> Result<()> {
1625         let _wp = wd::watch_millis("KeystoreDB::set_blob", 500);
1626 
1627         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1628             Self::set_blob_internal(tx, key_id.0, sc_type, blob, blob_metadata).need_gc()
1629         })
1630         .context("In set_blob.")
1631     }
1632 
1633     /// Why would we insert a deleted blob? This weird function is for the purpose of legacy
1634     /// key migration in the case where we bulk delete all the keys of an app or even a user.
1635     /// We use this to insert key blobs into the database which can then be garbage collected
1636     /// lazily by the key garbage collector.
set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()>1637     pub fn set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()> {
1638         let _wp = wd::watch_millis("KeystoreDB::set_deleted_blob", 500);
1639 
1640         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1641             Self::set_blob_internal(
1642                 tx,
1643                 Self::UNASSIGNED_KEY_ID,
1644                 SubComponentType::KEY_BLOB,
1645                 Some(blob),
1646                 Some(blob_metadata),
1647             )
1648             .need_gc()
1649         })
1650         .context("In set_deleted_blob.")
1651     }
1652 
set_blob_internal( tx: &Transaction, key_id: i64, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1653     fn set_blob_internal(
1654         tx: &Transaction,
1655         key_id: i64,
1656         sc_type: SubComponentType,
1657         blob: Option<&[u8]>,
1658         blob_metadata: Option<&BlobMetaData>,
1659     ) -> Result<()> {
1660         match (blob, sc_type) {
1661             (Some(blob), _) => {
1662                 tx.execute(
1663                     "INSERT INTO persistent.blobentry
1664                      (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);",
1665                     params![sc_type, key_id, blob],
1666                 )
1667                 .context("In set_blob_internal: Failed to insert blob.")?;
1668                 if let Some(blob_metadata) = blob_metadata {
1669                     let blob_id = tx
1670                         .query_row("SELECT MAX(id) FROM persistent.blobentry;", NO_PARAMS, |row| {
1671                             row.get(0)
1672                         })
1673                         .context("In set_blob_internal: Failed to get new blob id.")?;
1674                     blob_metadata
1675                         .store_in_db(blob_id, tx)
1676                         .context("In set_blob_internal: Trying to store blob metadata.")?;
1677                 }
1678             }
1679             (None, SubComponentType::CERT) | (None, SubComponentType::CERT_CHAIN) => {
1680                 tx.execute(
1681                     "DELETE FROM persistent.blobentry
1682                     WHERE subcomponent_type = ? AND keyentryid = ?;",
1683                     params![sc_type, key_id],
1684                 )
1685                 .context("In set_blob_internal: Failed to delete blob.")?;
1686             }
1687             (None, _) => {
1688                 return Err(KsError::sys())
1689                     .context("In set_blob_internal: Other blobs cannot be deleted in this way.");
1690             }
1691         }
1692         Ok(())
1693     }
1694 
1695     /// Inserts a collection of key parameters into the `persistent.keyparameter` table
1696     /// and associates them with the given `key_id`.
1697     #[cfg(test)]
insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()>1698     fn insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()> {
1699         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1700             Self::insert_keyparameter_internal(tx, key_id, params).no_gc()
1701         })
1702         .context("In insert_keyparameter.")
1703     }
1704 
insert_keyparameter_internal( tx: &Transaction, key_id: &KeyIdGuard, params: &[KeyParameter], ) -> Result<()>1705     fn insert_keyparameter_internal(
1706         tx: &Transaction,
1707         key_id: &KeyIdGuard,
1708         params: &[KeyParameter],
1709     ) -> Result<()> {
1710         let mut stmt = tx
1711             .prepare(
1712                 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
1713                 VALUES (?, ?, ?, ?);",
1714             )
1715             .context("In insert_keyparameter_internal: Failed to prepare statement.")?;
1716 
1717         for p in params.iter() {
1718             stmt.insert(params![
1719                 key_id.0,
1720                 p.get_tag().0,
1721                 p.key_parameter_value(),
1722                 p.security_level().0
1723             ])
1724             .with_context(|| {
1725                 format!("In insert_keyparameter_internal: Failed to insert {:?}", p)
1726             })?;
1727         }
1728         Ok(())
1729     }
1730 
1731     /// Insert a set of key entry specific metadata into the database.
1732     #[cfg(test)]
insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()>1733     fn insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()> {
1734         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1735             metadata.store_in_db(key_id.0, tx).no_gc()
1736         })
1737         .context("In insert_key_metadata.")
1738     }
1739 
1740     /// Stores a signed certificate chain signed by a remote provisioning server, keyed
1741     /// on the public key.
store_signed_attestation_certificate_chain( &mut self, raw_public_key: &[u8], batch_cert: &[u8], cert_chain: &[u8], expiration_date: i64, km_uuid: &Uuid, ) -> Result<()>1742     pub fn store_signed_attestation_certificate_chain(
1743         &mut self,
1744         raw_public_key: &[u8],
1745         batch_cert: &[u8],
1746         cert_chain: &[u8],
1747         expiration_date: i64,
1748         km_uuid: &Uuid,
1749     ) -> Result<()> {
1750         let _wp = wd::watch_millis("KeystoreDB::store_signed_attestation_certificate_chain", 500);
1751 
1752         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1753             let mut stmt = tx
1754                 .prepare(
1755                     "SELECT keyentryid
1756                     FROM persistent.keymetadata
1757                     WHERE tag = ? AND data = ? AND keyentryid IN
1758                     (SELECT id
1759                      FROM persistent.keyentry
1760                      WHERE
1761                         alias IS NULL AND
1762                         domain IS NULL AND
1763                         namespace IS NULL AND
1764                         key_type = ? AND
1765                         km_uuid = ?);",
1766                 )
1767                 .context("Failed to store attestation certificate chain.")?;
1768             let mut rows = stmt
1769                 .query(params![
1770                     KeyMetaData::AttestationRawPubKey,
1771                     raw_public_key,
1772                     KeyType::Attestation,
1773                     km_uuid
1774                 ])
1775                 .context("Failed to fetch keyid")?;
1776             let key_id = db_utils::with_rows_extract_one(&mut rows, |row| {
1777                 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?
1778                     .get(0)
1779                     .context("Failed to unpack id.")
1780             })
1781             .context("Failed to get key_id.")?;
1782             let num_updated = tx
1783                 .execute(
1784                     "UPDATE persistent.keyentry
1785                     SET alias = ?
1786                     WHERE id = ?;",
1787                     params!["signed", key_id],
1788                 )
1789                 .context("Failed to update alias.")?;
1790             if num_updated != 1 {
1791                 return Err(KsError::sys()).context("Alias not updated for the key.");
1792             }
1793             let mut metadata = KeyMetaData::new();
1794             metadata.add(KeyMetaEntry::AttestationExpirationDate(DateTime::from_millis_epoch(
1795                 expiration_date,
1796             )));
1797             metadata.store_in_db(key_id, tx).context("Failed to insert key metadata.")?;
1798             Self::set_blob_internal(
1799                 tx,
1800                 key_id,
1801                 SubComponentType::CERT_CHAIN,
1802                 Some(cert_chain),
1803                 None,
1804             )
1805             .context("Failed to insert cert chain")?;
1806             Self::set_blob_internal(tx, key_id, SubComponentType::CERT, Some(batch_cert), None)
1807                 .context("Failed to insert cert")?;
1808             Ok(()).no_gc()
1809         })
1810         .context("In store_signed_attestation_certificate_chain: ")
1811     }
1812 
1813     /// Assigns the next unassigned attestation key to a domain/namespace combo that does not
1814     /// currently have a key assigned to it.
assign_attestation_key( &mut self, domain: Domain, namespace: i64, km_uuid: &Uuid, ) -> Result<()>1815     pub fn assign_attestation_key(
1816         &mut self,
1817         domain: Domain,
1818         namespace: i64,
1819         km_uuid: &Uuid,
1820     ) -> Result<()> {
1821         let _wp = wd::watch_millis("KeystoreDB::assign_attestation_key", 500);
1822 
1823         match domain {
1824             Domain::APP | Domain::SELINUX => {}
1825             _ => {
1826                 return Err(KsError::sys()).context(format!(
1827                     concat!(
1828                         "In assign_attestation_key: Domain {:?} ",
1829                         "must be either App or SELinux.",
1830                     ),
1831                     domain
1832                 ));
1833             }
1834         }
1835         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1836             let result = tx
1837                 .execute(
1838                     "UPDATE persistent.keyentry
1839                         SET domain=?1, namespace=?2
1840                         WHERE
1841                             id =
1842                                 (SELECT MIN(id)
1843                                 FROM persistent.keyentry
1844                                 WHERE ALIAS IS NOT NULL
1845                                     AND domain IS NULL
1846                                     AND key_type IS ?3
1847                                     AND state IS ?4
1848                                     AND km_uuid IS ?5)
1849                             AND
1850                                 (SELECT COUNT(*)
1851                                 FROM persistent.keyentry
1852                                 WHERE domain=?1
1853                                     AND namespace=?2
1854                                     AND key_type IS ?3
1855                                     AND state IS ?4
1856                                     AND km_uuid IS ?5) = 0;",
1857                     params![
1858                         domain.0 as u32,
1859                         namespace,
1860                         KeyType::Attestation,
1861                         KeyLifeCycle::Live,
1862                         km_uuid,
1863                     ],
1864                 )
1865                 .context("Failed to assign attestation key")?;
1866             if result == 0 {
1867                 let (_, hw_info) = get_keymint_dev_by_uuid(km_uuid)
1868                     .context("Error in retrieving keymint device by UUID.")?;
1869                 log_rkp_error_stats(MetricsRkpError::OUT_OF_KEYS, &hw_info.securityLevel);
1870                 return Err(KsError::Rc(ResponseCode::OUT_OF_KEYS)).context("Out of keys.");
1871             } else if result > 1 {
1872                 return Err(KsError::sys())
1873                     .context(format!("Expected to update 1 entry, instead updated {}", result));
1874             }
1875             Ok(()).no_gc()
1876         })
1877         .context("In assign_attestation_key: ")
1878     }
1879 
1880     /// Retrieves num_keys number of attestation keys that have not yet been signed by a remote
1881     /// provisioning server, or the maximum number available if there are not num_keys number of
1882     /// entries in the table.
fetch_unsigned_attestation_keys( &mut self, num_keys: i32, km_uuid: &Uuid, ) -> Result<Vec<Vec<u8>>>1883     pub fn fetch_unsigned_attestation_keys(
1884         &mut self,
1885         num_keys: i32,
1886         km_uuid: &Uuid,
1887     ) -> Result<Vec<Vec<u8>>> {
1888         let _wp = wd::watch_millis("KeystoreDB::fetch_unsigned_attestation_keys", 500);
1889 
1890         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1891             let mut stmt = tx
1892                 .prepare(
1893                     "SELECT data
1894                     FROM persistent.keymetadata
1895                     WHERE tag = ? AND keyentryid IN
1896                         (SELECT id
1897                         FROM persistent.keyentry
1898                         WHERE
1899                             alias IS NULL AND
1900                             domain IS NULL AND
1901                             namespace IS NULL AND
1902                             key_type = ? AND
1903                             km_uuid = ?
1904                         LIMIT ?);",
1905                 )
1906                 .context("Failed to prepare statement")?;
1907             let rows = stmt
1908                 .query_map(
1909                     params![
1910                         KeyMetaData::AttestationMacedPublicKey,
1911                         KeyType::Attestation,
1912                         km_uuid,
1913                         num_keys
1914                     ],
1915                     |row| row.get(0),
1916                 )?
1917                 .collect::<rusqlite::Result<Vec<Vec<u8>>>>()
1918                 .context("Failed to execute statement")?;
1919             Ok(rows).no_gc()
1920         })
1921         .context("In fetch_unsigned_attestation_keys")
1922     }
1923 
1924     /// Removes any keys that have expired as of the current time. Returns the number of keys
1925     /// marked unreferenced that are bound to be garbage collected.
delete_expired_attestation_keys(&mut self) -> Result<i32>1926     pub fn delete_expired_attestation_keys(&mut self) -> Result<i32> {
1927         let _wp = wd::watch_millis("KeystoreDB::delete_expired_attestation_keys", 500);
1928 
1929         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1930             let mut stmt = tx
1931                 .prepare(
1932                     "SELECT keyentryid, data
1933                      FROM persistent.keymetadata
1934                      WHERE tag = ? AND keyentryid IN
1935                          (SELECT id
1936                          FROM persistent.keyentry
1937                          WHERE key_type = ?);",
1938                 )
1939                 .context("Failed to prepare query")?;
1940             let key_ids_to_check = stmt
1941                 .query_map(
1942                     params![KeyMetaData::AttestationExpirationDate, KeyType::Attestation],
1943                     |row| Ok((row.get(0)?, row.get(1)?)),
1944                 )?
1945                 .collect::<rusqlite::Result<Vec<(i64, DateTime)>>>()
1946                 .context("Failed to get date metadata")?;
1947             // Calculate curr_time with a discount factor to avoid a key that's milliseconds away
1948             // from expiration dodging this delete call.
1949             let curr_time = DateTime::from_millis_epoch(
1950                 SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
1951                     + EXPIRATION_BUFFER_MS,
1952             );
1953             let mut num_deleted = 0;
1954             for id in key_ids_to_check.iter().filter(|kt| kt.1 < curr_time).map(|kt| kt.0) {
1955                 if Self::mark_unreferenced(tx, id)? {
1956                     num_deleted += 1;
1957                 }
1958             }
1959             Ok(num_deleted).do_gc(num_deleted != 0)
1960         })
1961         .context("In delete_expired_attestation_keys: ")
1962     }
1963 
1964     /// Deletes all remotely provisioned attestation keys in the system, regardless of the state
1965     /// they are in. This is useful primarily as a testing mechanism.
delete_all_attestation_keys(&mut self) -> Result<i64>1966     pub fn delete_all_attestation_keys(&mut self) -> Result<i64> {
1967         let _wp = wd::watch_millis("KeystoreDB::delete_all_attestation_keys", 500);
1968 
1969         self.with_transaction(TransactionBehavior::Immediate, |tx| {
1970             let mut stmt = tx
1971                 .prepare(
1972                     "SELECT id FROM persistent.keyentry
1973                     WHERE key_type IS ?;",
1974                 )
1975                 .context("Failed to prepare statement")?;
1976             let keys_to_delete = stmt
1977                 .query_map(params![KeyType::Attestation], |row| row.get(0))?
1978                 .collect::<rusqlite::Result<Vec<i64>>>()
1979                 .context("Failed to execute statement")?;
1980             let num_deleted = keys_to_delete
1981                 .iter()
1982                 .map(|id| Self::mark_unreferenced(tx, *id))
1983                 .collect::<Result<Vec<bool>>>()
1984                 .context("Failed to execute mark_unreferenced on a keyid")?
1985                 .into_iter()
1986                 .filter(|result| *result)
1987                 .count() as i64;
1988             Ok(num_deleted).do_gc(num_deleted != 0)
1989         })
1990         .context("In delete_all_attestation_keys: ")
1991     }
1992 
1993     /// Counts the number of keys that will expire by the provided epoch date and the number of
1994     /// keys not currently assigned to a domain.
get_attestation_pool_status( &mut self, date: i64, km_uuid: &Uuid, ) -> Result<AttestationPoolStatus>1995     pub fn get_attestation_pool_status(
1996         &mut self,
1997         date: i64,
1998         km_uuid: &Uuid,
1999     ) -> Result<AttestationPoolStatus> {
2000         let _wp = wd::watch_millis("KeystoreDB::get_attestation_pool_status", 500);
2001 
2002         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2003             let mut stmt = tx.prepare(
2004                 "SELECT data
2005                  FROM persistent.keymetadata
2006                  WHERE tag = ? AND keyentryid IN
2007                      (SELECT id
2008                       FROM persistent.keyentry
2009                       WHERE alias IS NOT NULL
2010                             AND key_type = ?
2011                             AND km_uuid = ?
2012                             AND state = ?);",
2013             )?;
2014             let times = stmt
2015                 .query_map(
2016                     params![
2017                         KeyMetaData::AttestationExpirationDate,
2018                         KeyType::Attestation,
2019                         km_uuid,
2020                         KeyLifeCycle::Live
2021                     ],
2022                     |row| row.get(0),
2023                 )?
2024                 .collect::<rusqlite::Result<Vec<DateTime>>>()
2025                 .context("Failed to execute metadata statement")?;
2026             let expiring =
2027                 times.iter().filter(|time| time < &&DateTime::from_millis_epoch(date)).count()
2028                     as i32;
2029             stmt = tx.prepare(
2030                 "SELECT alias, domain
2031                  FROM persistent.keyentry
2032                  WHERE key_type = ? AND km_uuid = ? AND state = ?;",
2033             )?;
2034             let rows = stmt
2035                 .query_map(params![KeyType::Attestation, km_uuid, KeyLifeCycle::Live], |row| {
2036                     Ok((row.get(0)?, row.get(1)?))
2037                 })?
2038                 .collect::<rusqlite::Result<Vec<(Option<String>, Option<u32>)>>>()
2039                 .context("Failed to execute keyentry statement")?;
2040             let mut unassigned = 0i32;
2041             let mut attested = 0i32;
2042             let total = rows.len() as i32;
2043             for (alias, domain) in rows {
2044                 match (alias, domain) {
2045                     (Some(_alias), None) => {
2046                         attested += 1;
2047                         unassigned += 1;
2048                     }
2049                     (Some(_alias), Some(_domain)) => {
2050                         attested += 1;
2051                     }
2052                     _ => {}
2053                 }
2054             }
2055             Ok(AttestationPoolStatus { expiring, unassigned, attested, total }).no_gc()
2056         })
2057         .context("In get_attestation_pool_status: ")
2058     }
2059 
query_kid_for_attestation_key_and_cert_chain( &self, tx: &Transaction, domain: Domain, namespace: i64, km_uuid: &Uuid, ) -> Result<Option<i64>>2060     fn query_kid_for_attestation_key_and_cert_chain(
2061         &self,
2062         tx: &Transaction,
2063         domain: Domain,
2064         namespace: i64,
2065         km_uuid: &Uuid,
2066     ) -> Result<Option<i64>> {
2067         let mut stmt = tx.prepare(
2068             "SELECT id
2069              FROM persistent.keyentry
2070              WHERE key_type = ?
2071                    AND domain = ?
2072                    AND namespace = ?
2073                    AND state = ?
2074                    AND km_uuid = ?;",
2075         )?;
2076         let rows = stmt
2077             .query_map(
2078                 params![
2079                     KeyType::Attestation,
2080                     domain.0 as u32,
2081                     namespace,
2082                     KeyLifeCycle::Live,
2083                     km_uuid
2084                 ],
2085                 |row| row.get(0),
2086             )?
2087             .collect::<rusqlite::Result<Vec<i64>>>()
2088             .context("query failed.")?;
2089         if rows.is_empty() {
2090             return Ok(None);
2091         }
2092         Ok(Some(rows[0]))
2093     }
2094 
2095     /// Fetches the private key and corresponding certificate chain assigned to a
2096     /// domain/namespace pair. Will either return nothing if the domain/namespace is
2097     /// not assigned, or one CertificateChain.
retrieve_attestation_key_and_cert_chain( &mut self, domain: Domain, namespace: i64, km_uuid: &Uuid, ) -> Result<Option<(KeyIdGuard, CertificateChain)>>2098     pub fn retrieve_attestation_key_and_cert_chain(
2099         &mut self,
2100         domain: Domain,
2101         namespace: i64,
2102         km_uuid: &Uuid,
2103     ) -> Result<Option<(KeyIdGuard, CertificateChain)>> {
2104         let _wp = wd::watch_millis("KeystoreDB::retrieve_attestation_key_and_cert_chain", 500);
2105 
2106         match domain {
2107             Domain::APP | Domain::SELINUX => {}
2108             _ => {
2109                 return Err(KsError::sys())
2110                     .context(format!("Domain {:?} must be either App or SELinux.", domain));
2111             }
2112         }
2113 
2114         self.delete_expired_attestation_keys().context(
2115             "In retrieve_attestation_key_and_cert_chain: failed to prune expired attestation keys",
2116         )?;
2117         let tx = self.conn.unchecked_transaction().context(
2118             "In retrieve_attestation_key_and_cert_chain: Failed to initialize transaction.",
2119         )?;
2120         let key_id: i64 = match self
2121             .query_kid_for_attestation_key_and_cert_chain(&tx, domain, namespace, km_uuid)?
2122         {
2123             None => return Ok(None),
2124             Some(kid) => kid,
2125         };
2126         tx.commit()
2127             .context("In retrieve_attestation_key_and_cert_chain: Failed to commit keyid query")?;
2128         let key_id_guard = KEY_ID_LOCK.get(key_id);
2129         let tx = self.conn.unchecked_transaction().context(
2130             "In retrieve_attestation_key_and_cert_chain: Failed to initialize transaction.",
2131         )?;
2132         let mut stmt = tx.prepare(
2133             "SELECT subcomponent_type, blob
2134             FROM persistent.blobentry
2135             WHERE keyentryid = ?;",
2136         )?;
2137         let rows = stmt
2138             .query_map(params![key_id_guard.id()], |row| Ok((row.get(0)?, row.get(1)?)))?
2139             .collect::<rusqlite::Result<Vec<(SubComponentType, Vec<u8>)>>>()
2140             .context("query failed.")?;
2141         if rows.is_empty() {
2142             return Ok(None);
2143         } else if rows.len() != 3 {
2144             return Err(KsError::sys()).context(format!(
2145                 concat!(
2146                     "Expected to get a single attestation",
2147                     "key, cert, and cert chain for a total of 3 entries, but instead got {}."
2148                 ),
2149                 rows.len()
2150             ));
2151         }
2152         let mut km_blob: Vec<u8> = Vec::new();
2153         let mut cert_chain_blob: Vec<u8> = Vec::new();
2154         let mut batch_cert_blob: Vec<u8> = Vec::new();
2155         for row in rows {
2156             let sub_type: SubComponentType = row.0;
2157             match sub_type {
2158                 SubComponentType::KEY_BLOB => {
2159                     km_blob = row.1;
2160                 }
2161                 SubComponentType::CERT_CHAIN => {
2162                     cert_chain_blob = row.1;
2163                 }
2164                 SubComponentType::CERT => {
2165                     batch_cert_blob = row.1;
2166                 }
2167                 _ => Err(KsError::sys()).context("Unknown or incorrect subcomponent type.")?,
2168             }
2169         }
2170         Ok(Some((
2171             key_id_guard,
2172             CertificateChain {
2173                 private_key: ZVec::try_from(km_blob)?,
2174                 batch_cert: batch_cert_blob,
2175                 cert_chain: cert_chain_blob,
2176             },
2177         )))
2178     }
2179 
2180     /// Updates the alias column of the given key id `newid` with the given alias,
2181     /// and atomically, removes the alias, domain, and namespace from another row
2182     /// with the same alias-domain-namespace tuple if such row exits.
2183     /// Returns Ok(true) if an old key was marked unreferenced as a hint to the garbage
2184     /// collector.
rebind_alias( tx: &Transaction, newid: &KeyIdGuard, alias: &str, domain: &Domain, namespace: &i64, key_type: KeyType, ) -> Result<bool>2185     fn rebind_alias(
2186         tx: &Transaction,
2187         newid: &KeyIdGuard,
2188         alias: &str,
2189         domain: &Domain,
2190         namespace: &i64,
2191         key_type: KeyType,
2192     ) -> Result<bool> {
2193         match *domain {
2194             Domain::APP | Domain::SELINUX => {}
2195             _ => {
2196                 return Err(KsError::sys()).context(format!(
2197                     "In rebind_alias: Domain {:?} must be either App or SELinux.",
2198                     domain
2199                 ));
2200             }
2201         }
2202         let updated = tx
2203             .execute(
2204                 "UPDATE persistent.keyentry
2205                  SET alias = NULL, domain = NULL, namespace = NULL, state = ?
2206                  WHERE alias = ? AND domain = ? AND namespace = ? AND key_type = ?;",
2207                 params![KeyLifeCycle::Unreferenced, alias, domain.0 as u32, namespace, key_type],
2208             )
2209             .context("In rebind_alias: Failed to rebind existing entry.")?;
2210         let result = tx
2211             .execute(
2212                 "UPDATE persistent.keyentry
2213                     SET alias = ?, state = ?
2214                     WHERE id = ? AND domain = ? AND namespace = ? AND state = ? AND key_type = ?;",
2215                 params![
2216                     alias,
2217                     KeyLifeCycle::Live,
2218                     newid.0,
2219                     domain.0 as u32,
2220                     *namespace,
2221                     KeyLifeCycle::Existing,
2222                     key_type,
2223                 ],
2224             )
2225             .context("In rebind_alias: Failed to set alias.")?;
2226         if result != 1 {
2227             return Err(KsError::sys()).context(format!(
2228                 "In rebind_alias: Expected to update a single entry but instead updated {}.",
2229                 result
2230             ));
2231         }
2232         Ok(updated != 0)
2233     }
2234 
2235     /// Moves the key given by KeyIdGuard to the new location at `destination`. If the destination
2236     /// is already occupied by a key, this function fails with `ResponseCode::INVALID_ARGUMENT`.
migrate_key_namespace( &mut self, key_id_guard: KeyIdGuard, destination: &KeyDescriptor, caller_uid: u32, check_permission: impl Fn(&KeyDescriptor) -> Result<()>, ) -> Result<()>2237     pub fn migrate_key_namespace(
2238         &mut self,
2239         key_id_guard: KeyIdGuard,
2240         destination: &KeyDescriptor,
2241         caller_uid: u32,
2242         check_permission: impl Fn(&KeyDescriptor) -> Result<()>,
2243     ) -> Result<()> {
2244         let _wp = wd::watch_millis("KeystoreDB::migrate_key_namespace", 500);
2245 
2246         let destination = match destination.domain {
2247             Domain::APP => KeyDescriptor { nspace: caller_uid as i64, ..(*destination).clone() },
2248             Domain::SELINUX => (*destination).clone(),
2249             domain => {
2250                 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
2251                     .context(format!("Domain {:?} must be either APP or SELINUX.", domain));
2252             }
2253         };
2254 
2255         // Security critical: Must return immediately on failure. Do not remove the '?';
2256         check_permission(&destination)
2257             .context("In migrate_key_namespace: Trying to check permission.")?;
2258 
2259         let alias = destination
2260             .alias
2261             .as_ref()
2262             .ok_or(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
2263             .context("In migrate_key_namespace: Alias must be specified.")?;
2264 
2265         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2266             // Query the destination location. If there is a key, the migration request fails.
2267             if tx
2268                 .query_row(
2269                     "SELECT id FROM persistent.keyentry
2270                      WHERE alias = ? AND domain = ? AND namespace = ?;",
2271                     params![alias, destination.domain.0, destination.nspace],
2272                     |_| Ok(()),
2273                 )
2274                 .optional()
2275                 .context("Failed to query destination.")?
2276                 .is_some()
2277             {
2278                 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
2279                     .context("Target already exists.");
2280             }
2281 
2282             let updated = tx
2283                 .execute(
2284                     "UPDATE persistent.keyentry
2285                  SET alias = ?, domain = ?, namespace = ?
2286                  WHERE id = ?;",
2287                     params![alias, destination.domain.0, destination.nspace, key_id_guard.id()],
2288                 )
2289                 .context("Failed to update key entry.")?;
2290 
2291             if updated != 1 {
2292                 return Err(KsError::sys())
2293                     .context(format!("Update succeeded, but {} rows were updated.", updated));
2294             }
2295             Ok(()).no_gc()
2296         })
2297         .context("In migrate_key_namespace:")
2298     }
2299 
2300     /// Store a new key in a single transaction.
2301     /// The function creates a new key entry, populates the blob, key parameter, and metadata
2302     /// fields, and rebinds the given alias to the new key.
2303     /// The boolean returned is a hint for the garbage collector. If true, a key was replaced,
2304     /// is now unreferenced and needs to be collected.
2305     #[allow(clippy::too_many_arguments)]
store_new_key( &mut self, key: &KeyDescriptor, key_type: KeyType, params: &[KeyParameter], blob_info: &BlobInfo, cert_info: &CertificateInfo, metadata: &KeyMetaData, km_uuid: &Uuid, ) -> Result<KeyIdGuard>2306     pub fn store_new_key(
2307         &mut self,
2308         key: &KeyDescriptor,
2309         key_type: KeyType,
2310         params: &[KeyParameter],
2311         blob_info: &BlobInfo,
2312         cert_info: &CertificateInfo,
2313         metadata: &KeyMetaData,
2314         km_uuid: &Uuid,
2315     ) -> Result<KeyIdGuard> {
2316         let _wp = wd::watch_millis("KeystoreDB::store_new_key", 500);
2317 
2318         let (alias, domain, namespace) = match key {
2319             KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None }
2320             | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => {
2321                 (alias, key.domain, nspace)
2322             }
2323             _ => {
2324                 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
2325                     .context("In store_new_key: Need alias and domain must be APP or SELINUX.")
2326             }
2327         };
2328         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2329             let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid)
2330                 .context("Trying to create new key entry.")?;
2331             let BlobInfo { blob, metadata: blob_metadata, superseded_blob } = *blob_info;
2332 
2333             // In some occasions the key blob is already upgraded during the import.
2334             // In order to make sure it gets properly deleted it is inserted into the
2335             // database here and then immediately replaced by the superseding blob.
2336             // The garbage collector will then subject the blob to deleteKey of the
2337             // KM back end to permanently invalidate the key.
2338             let need_gc = if let Some((blob, blob_metadata)) = superseded_blob {
2339                 Self::set_blob_internal(
2340                     tx,
2341                     key_id.id(),
2342                     SubComponentType::KEY_BLOB,
2343                     Some(blob),
2344                     Some(blob_metadata),
2345                 )
2346                 .context("Trying to insert superseded key blob.")?;
2347                 true
2348             } else {
2349                 false
2350             };
2351 
2352             Self::set_blob_internal(
2353                 tx,
2354                 key_id.id(),
2355                 SubComponentType::KEY_BLOB,
2356                 Some(blob),
2357                 Some(blob_metadata),
2358             )
2359             .context("Trying to insert the key blob.")?;
2360             if let Some(cert) = &cert_info.cert {
2361                 Self::set_blob_internal(tx, key_id.id(), SubComponentType::CERT, Some(cert), None)
2362                     .context("Trying to insert the certificate.")?;
2363             }
2364             if let Some(cert_chain) = &cert_info.cert_chain {
2365                 Self::set_blob_internal(
2366                     tx,
2367                     key_id.id(),
2368                     SubComponentType::CERT_CHAIN,
2369                     Some(cert_chain),
2370                     None,
2371                 )
2372                 .context("Trying to insert the certificate chain.")?;
2373             }
2374             Self::insert_keyparameter_internal(tx, &key_id, params)
2375                 .context("Trying to insert key parameters.")?;
2376             metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?;
2377             let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type)
2378                 .context("Trying to rebind alias.")?
2379                 || need_gc;
2380             Ok(key_id).do_gc(need_gc)
2381         })
2382         .context("In store_new_key.")
2383     }
2384 
2385     /// Store a new certificate
2386     /// The function creates a new key entry, populates the blob field and metadata, and rebinds
2387     /// the given alias to the new cert.
store_new_certificate( &mut self, key: &KeyDescriptor, key_type: KeyType, cert: &[u8], km_uuid: &Uuid, ) -> Result<KeyIdGuard>2388     pub fn store_new_certificate(
2389         &mut self,
2390         key: &KeyDescriptor,
2391         key_type: KeyType,
2392         cert: &[u8],
2393         km_uuid: &Uuid,
2394     ) -> Result<KeyIdGuard> {
2395         let _wp = wd::watch_millis("KeystoreDB::store_new_certificate", 500);
2396 
2397         let (alias, domain, namespace) = match key {
2398             KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None }
2399             | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => {
2400                 (alias, key.domain, nspace)
2401             }
2402             _ => {
2403                 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)).context(
2404                     "In store_new_certificate: Need alias and domain must be APP or SELINUX.",
2405                 )
2406             }
2407         };
2408         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2409             let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid)
2410                 .context("Trying to create new key entry.")?;
2411 
2412             Self::set_blob_internal(
2413                 tx,
2414                 key_id.id(),
2415                 SubComponentType::CERT_CHAIN,
2416                 Some(cert),
2417                 None,
2418             )
2419             .context("Trying to insert certificate.")?;
2420 
2421             let mut metadata = KeyMetaData::new();
2422             metadata.add(KeyMetaEntry::CreationDate(
2423                 DateTime::now().context("Trying to make creation time.")?,
2424             ));
2425 
2426             metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?;
2427 
2428             let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type)
2429                 .context("Trying to rebind alias.")?;
2430             Ok(key_id).do_gc(need_gc)
2431         })
2432         .context("In store_new_certificate.")
2433     }
2434 
2435     // Helper function loading the key_id given the key descriptor
2436     // tuple comprising domain, namespace, and alias.
2437     // Requires a valid transaction.
load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64>2438     fn load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64> {
2439         let alias = key
2440             .alias
2441             .as_ref()
2442             .map_or_else(|| Err(KsError::sys()), Ok)
2443             .context("In load_key_entry_id: Alias must be specified.")?;
2444         let mut stmt = tx
2445             .prepare(
2446                 "SELECT id FROM persistent.keyentry
2447                     WHERE
2448                     key_type = ?
2449                     AND domain = ?
2450                     AND namespace = ?
2451                     AND alias = ?
2452                     AND state = ?;",
2453             )
2454             .context("In load_key_entry_id: Failed to select from keyentry table.")?;
2455         let mut rows = stmt
2456             .query(params![key_type, key.domain.0 as u32, key.nspace, alias, KeyLifeCycle::Live])
2457             .context("In load_key_entry_id: Failed to read from keyentry table.")?;
2458         db_utils::with_rows_extract_one(&mut rows, |row| {
2459             row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?
2460                 .get(0)
2461                 .context("Failed to unpack id.")
2462         })
2463         .context("In load_key_entry_id.")
2464     }
2465 
2466     /// This helper function completes the access tuple of a key, which is required
2467     /// to perform access control. The strategy depends on the `domain` field in the
2468     /// key descriptor.
2469     /// * Domain::SELINUX: The access tuple is complete and this function only loads
2470     ///       the key_id for further processing.
2471     /// * Domain::APP: Like Domain::SELINUX, but the tuple is completed by `caller_uid`
2472     ///       which serves as the namespace.
2473     /// * Domain::GRANT: The grant table is queried for the `key_id` and the
2474     ///       `access_vector`.
2475     /// * Domain::KEY_ID: The keyentry table is queried for the owning `domain` and
2476     ///       `namespace`.
2477     /// In each case the information returned is sufficient to perform the access
2478     /// check and the key id can be used to load further key artifacts.
load_access_tuple( tx: &Transaction, key: &KeyDescriptor, key_type: KeyType, caller_uid: u32, ) -> Result<(i64, KeyDescriptor, Option<KeyPermSet>)>2479     fn load_access_tuple(
2480         tx: &Transaction,
2481         key: &KeyDescriptor,
2482         key_type: KeyType,
2483         caller_uid: u32,
2484     ) -> Result<(i64, KeyDescriptor, Option<KeyPermSet>)> {
2485         match key.domain {
2486             // Domain App or SELinux. In this case we load the key_id from
2487             // the keyentry database for further loading of key components.
2488             // We already have the full access tuple to perform access control.
2489             // The only distinction is that we use the caller_uid instead
2490             // of the caller supplied namespace if the domain field is
2491             // Domain::APP.
2492             Domain::APP | Domain::SELINUX => {
2493                 let mut access_key = key.clone();
2494                 if access_key.domain == Domain::APP {
2495                     access_key.nspace = caller_uid as i64;
2496                 }
2497                 let key_id = Self::load_key_entry_id(tx, &access_key, key_type)
2498                     .with_context(|| format!("With key.domain = {:?}.", access_key.domain))?;
2499 
2500                 Ok((key_id, access_key, None))
2501             }
2502 
2503             // Domain::GRANT. In this case we load the key_id and the access_vector
2504             // from the grant table.
2505             Domain::GRANT => {
2506                 let mut stmt = tx
2507                     .prepare(
2508                         "SELECT keyentryid, access_vector FROM persistent.grant
2509                             WHERE grantee = ? AND id = ? AND
2510                             (SELECT state FROM persistent.keyentry WHERE id = keyentryid) = ?;",
2511                     )
2512                     .context("Domain::GRANT prepare statement failed")?;
2513                 let mut rows = stmt
2514                     .query(params![caller_uid as i64, key.nspace, KeyLifeCycle::Live])
2515                     .context("Domain:Grant: query failed.")?;
2516                 let (key_id, access_vector): (i64, i32) =
2517                     db_utils::with_rows_extract_one(&mut rows, |row| {
2518                         let r =
2519                             row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?;
2520                         Ok((
2521                             r.get(0).context("Failed to unpack key_id.")?,
2522                             r.get(1).context("Failed to unpack access_vector.")?,
2523                         ))
2524                     })
2525                     .context("Domain::GRANT.")?;
2526                 Ok((key_id, key.clone(), Some(access_vector.into())))
2527             }
2528 
2529             // Domain::KEY_ID. In this case we load the domain and namespace from the
2530             // keyentry database because we need them for access control.
2531             Domain::KEY_ID => {
2532                 let (domain, namespace): (Domain, i64) = {
2533                     let mut stmt = tx
2534                         .prepare(
2535                             "SELECT domain, namespace FROM persistent.keyentry
2536                                 WHERE
2537                                 id = ?
2538                                 AND state = ?;",
2539                         )
2540                         .context("Domain::KEY_ID: prepare statement failed")?;
2541                     let mut rows = stmt
2542                         .query(params![key.nspace, KeyLifeCycle::Live])
2543                         .context("Domain::KEY_ID: query failed.")?;
2544                     db_utils::with_rows_extract_one(&mut rows, |row| {
2545                         let r =
2546                             row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?;
2547                         Ok((
2548                             Domain(r.get(0).context("Failed to unpack domain.")?),
2549                             r.get(1).context("Failed to unpack namespace.")?,
2550                         ))
2551                     })
2552                     .context("Domain::KEY_ID.")?
2553                 };
2554 
2555                 // We may use a key by id after loading it by grant.
2556                 // In this case we have to check if the caller has a grant for this particular
2557                 // key. We can skip this if we already know that the caller is the owner.
2558                 // But we cannot know this if domain is anything but App. E.g. in the case
2559                 // of Domain::SELINUX we have to speculatively check for grants because we have to
2560                 // consult the SEPolicy before we know if the caller is the owner.
2561                 let access_vector: Option<KeyPermSet> =
2562                     if domain != Domain::APP || namespace != caller_uid as i64 {
2563                         let access_vector: Option<i32> = tx
2564                             .query_row(
2565                                 "SELECT access_vector FROM persistent.grant
2566                                 WHERE grantee = ? AND keyentryid = ?;",
2567                                 params![caller_uid as i64, key.nspace],
2568                                 |row| row.get(0),
2569                             )
2570                             .optional()
2571                             .context("Domain::KEY_ID: query grant failed.")?;
2572                         access_vector.map(|p| p.into())
2573                     } else {
2574                         None
2575                     };
2576 
2577                 let key_id = key.nspace;
2578                 let mut access_key: KeyDescriptor = key.clone();
2579                 access_key.domain = domain;
2580                 access_key.nspace = namespace;
2581 
2582                 Ok((key_id, access_key, access_vector))
2583             }
2584             _ => Err(anyhow!(KsError::sys())),
2585         }
2586     }
2587 
load_blob_components( key_id: i64, load_bits: KeyEntryLoadBits, tx: &Transaction, ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)>2588     fn load_blob_components(
2589         key_id: i64,
2590         load_bits: KeyEntryLoadBits,
2591         tx: &Transaction,
2592     ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)> {
2593         let mut stmt = tx
2594             .prepare(
2595                 "SELECT MAX(id), subcomponent_type, blob FROM persistent.blobentry
2596                     WHERE keyentryid = ? GROUP BY subcomponent_type;",
2597             )
2598             .context("In load_blob_components: prepare statement failed.")?;
2599 
2600         let mut rows =
2601             stmt.query(params![key_id]).context("In load_blob_components: query failed.")?;
2602 
2603         let mut key_blob: Option<(i64, Vec<u8>)> = None;
2604         let mut cert_blob: Option<Vec<u8>> = None;
2605         let mut cert_chain_blob: Option<Vec<u8>> = None;
2606         let mut has_km_blob: bool = false;
2607         db_utils::with_rows_extract_all(&mut rows, |row| {
2608             let sub_type: SubComponentType =
2609                 row.get(1).context("Failed to extract subcomponent_type.")?;
2610             has_km_blob = has_km_blob || sub_type == SubComponentType::KEY_BLOB;
2611             match (sub_type, load_bits.load_public(), load_bits.load_km()) {
2612                 (SubComponentType::KEY_BLOB, _, true) => {
2613                     key_blob = Some((
2614                         row.get(0).context("Failed to extract key blob id.")?,
2615                         row.get(2).context("Failed to extract key blob.")?,
2616                     ));
2617                 }
2618                 (SubComponentType::CERT, true, _) => {
2619                     cert_blob =
2620                         Some(row.get(2).context("Failed to extract public certificate blob.")?);
2621                 }
2622                 (SubComponentType::CERT_CHAIN, true, _) => {
2623                     cert_chain_blob =
2624                         Some(row.get(2).context("Failed to extract certificate chain blob.")?);
2625                 }
2626                 (SubComponentType::CERT, _, _)
2627                 | (SubComponentType::CERT_CHAIN, _, _)
2628                 | (SubComponentType::KEY_BLOB, _, _) => {}
2629                 _ => Err(KsError::sys()).context("Unknown subcomponent type.")?,
2630             }
2631             Ok(())
2632         })
2633         .context("In load_blob_components.")?;
2634 
2635         let blob_info = key_blob.map_or::<Result<_>, _>(Ok(None), |(blob_id, blob)| {
2636             Ok(Some((
2637                 blob,
2638                 BlobMetaData::load_from_db(blob_id, tx)
2639                     .context("In load_blob_components: Trying to load blob_metadata.")?,
2640             )))
2641         })?;
2642 
2643         Ok((has_km_blob, blob_info, cert_blob, cert_chain_blob))
2644     }
2645 
load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>>2646     fn load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>> {
2647         let mut stmt = tx
2648             .prepare(
2649                 "SELECT tag, data, security_level from persistent.keyparameter
2650                     WHERE keyentryid = ?;",
2651             )
2652             .context("In load_key_parameters: prepare statement failed.")?;
2653 
2654         let mut parameters: Vec<KeyParameter> = Vec::new();
2655 
2656         let mut rows =
2657             stmt.query(params![key_id]).context("In load_key_parameters: query failed.")?;
2658         db_utils::with_rows_extract_all(&mut rows, |row| {
2659             let tag = Tag(row.get(0).context("Failed to read tag.")?);
2660             let sec_level = SecurityLevel(row.get(2).context("Failed to read sec_level.")?);
2661             parameters.push(
2662                 KeyParameter::new_from_sql(tag, &SqlField::new(1, row), sec_level)
2663                     .context("Failed to read KeyParameter.")?,
2664             );
2665             Ok(())
2666         })
2667         .context("In load_key_parameters.")?;
2668 
2669         Ok(parameters)
2670     }
2671 
2672     /// Decrements the usage count of a limited use key. This function first checks whether the
2673     /// usage has been exhausted, if not, decreases the usage count. If the usage count reaches
2674     /// zero, the key also gets marked unreferenced and scheduled for deletion.
2675     /// Returns Ok(true) if the key was marked unreferenced as a hint to the garbage collector.
check_and_update_key_usage_count(&mut self, key_id: i64) -> Result<()>2676     pub fn check_and_update_key_usage_count(&mut self, key_id: i64) -> Result<()> {
2677         let _wp = wd::watch_millis("KeystoreDB::check_and_update_key_usage_count", 500);
2678 
2679         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2680             let limit: Option<i32> = tx
2681                 .query_row(
2682                     "SELECT data FROM persistent.keyparameter WHERE keyentryid = ? AND tag = ?;",
2683                     params![key_id, Tag::USAGE_COUNT_LIMIT.0],
2684                     |row| row.get(0),
2685                 )
2686                 .optional()
2687                 .context("Trying to load usage count")?;
2688 
2689             let limit = limit
2690                 .ok_or(KsError::Km(ErrorCode::INVALID_KEY_BLOB))
2691                 .context("The Key no longer exists. Key is exhausted.")?;
2692 
2693             tx.execute(
2694                 "UPDATE persistent.keyparameter
2695                  SET data = data - 1
2696                  WHERE keyentryid = ? AND tag = ? AND data > 0;",
2697                 params![key_id, Tag::USAGE_COUNT_LIMIT.0],
2698             )
2699             .context("Failed to update key usage count.")?;
2700 
2701             match limit {
2702                 1 => Self::mark_unreferenced(tx, key_id)
2703                     .map(|need_gc| (need_gc, ()))
2704                     .context("Trying to mark limited use key for deletion."),
2705                 0 => Err(KsError::Km(ErrorCode::INVALID_KEY_BLOB)).context("Key is exhausted."),
2706                 _ => Ok(()).no_gc(),
2707             }
2708         })
2709         .context("In check_and_update_key_usage_count.")
2710     }
2711 
2712     /// Load a key entry by the given key descriptor.
2713     /// It uses the `check_permission` callback to verify if the access is allowed
2714     /// given the key access tuple read from the database using `load_access_tuple`.
2715     /// With `load_bits` the caller may specify which blobs shall be loaded from
2716     /// the blob database.
load_key_entry( &mut self, key: &KeyDescriptor, key_type: KeyType, load_bits: KeyEntryLoadBits, caller_uid: u32, check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, ) -> Result<(KeyIdGuard, KeyEntry)>2717     pub fn load_key_entry(
2718         &mut self,
2719         key: &KeyDescriptor,
2720         key_type: KeyType,
2721         load_bits: KeyEntryLoadBits,
2722         caller_uid: u32,
2723         check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
2724     ) -> Result<(KeyIdGuard, KeyEntry)> {
2725         let _wp = wd::watch_millis("KeystoreDB::load_key_entry", 500);
2726 
2727         loop {
2728             match self.load_key_entry_internal(
2729                 key,
2730                 key_type,
2731                 load_bits,
2732                 caller_uid,
2733                 &check_permission,
2734             ) {
2735                 Ok(result) => break Ok(result),
2736                 Err(e) => {
2737                     if Self::is_locked_error(&e) {
2738                         std::thread::sleep(std::time::Duration::from_micros(500));
2739                         continue;
2740                     } else {
2741                         return Err(e).context("In load_key_entry.");
2742                     }
2743                 }
2744             }
2745         }
2746     }
2747 
load_key_entry_internal( &mut self, key: &KeyDescriptor, key_type: KeyType, load_bits: KeyEntryLoadBits, caller_uid: u32, check_permission: &impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, ) -> Result<(KeyIdGuard, KeyEntry)>2748     fn load_key_entry_internal(
2749         &mut self,
2750         key: &KeyDescriptor,
2751         key_type: KeyType,
2752         load_bits: KeyEntryLoadBits,
2753         caller_uid: u32,
2754         check_permission: &impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
2755     ) -> Result<(KeyIdGuard, KeyEntry)> {
2756         // KEY ID LOCK 1/2
2757         // If we got a key descriptor with a key id we can get the lock right away.
2758         // Otherwise we have to defer it until we know the key id.
2759         let key_id_guard = match key.domain {
2760             Domain::KEY_ID => Some(KEY_ID_LOCK.get(key.nspace)),
2761             _ => None,
2762         };
2763 
2764         let tx = self
2765             .conn
2766             .unchecked_transaction()
2767             .context("In load_key_entry: Failed to initialize transaction.")?;
2768 
2769         // Load the key_id and complete the access control tuple.
2770         let (key_id, access_key_descriptor, access_vector) =
2771             Self::load_access_tuple(&tx, key, key_type, caller_uid)
2772                 .context("In load_key_entry.")?;
2773 
2774         // Perform access control. It is vital that we return here if the permission is denied.
2775         // So do not touch that '?' at the end.
2776         check_permission(&access_key_descriptor, access_vector).context("In load_key_entry.")?;
2777 
2778         // KEY ID LOCK 2/2
2779         // If we did not get a key id lock by now, it was because we got a key descriptor
2780         // without a key id. At this point we got the key id, so we can try and get a lock.
2781         // However, we cannot block here, because we are in the middle of the transaction.
2782         // So first we try to get the lock non blocking. If that fails, we roll back the
2783         // transaction and block until we get the lock. After we successfully got the lock,
2784         // we start a new transaction and load the access tuple again.
2785         //
2786         // We don't need to perform access control again, because we already established
2787         // that the caller had access to the given key. But we need to make sure that the
2788         // key id still exists. So we have to load the key entry by key id this time.
2789         let (key_id_guard, tx) = match key_id_guard {
2790             None => match KEY_ID_LOCK.try_get(key_id) {
2791                 None => {
2792                     // Roll back the transaction.
2793                     tx.rollback().context("In load_key_entry: Failed to roll back transaction.")?;
2794 
2795                     // Block until we have a key id lock.
2796                     let key_id_guard = KEY_ID_LOCK.get(key_id);
2797 
2798                     // Create a new transaction.
2799                     let tx = self
2800                         .conn
2801                         .unchecked_transaction()
2802                         .context("In load_key_entry: Failed to initialize transaction.")?;
2803 
2804                     Self::load_access_tuple(
2805                         &tx,
2806                         // This time we have to load the key by the retrieved key id, because the
2807                         // alias may have been rebound after we rolled back the transaction.
2808                         &KeyDescriptor {
2809                             domain: Domain::KEY_ID,
2810                             nspace: key_id,
2811                             ..Default::default()
2812                         },
2813                         key_type,
2814                         caller_uid,
2815                     )
2816                     .context("In load_key_entry. (deferred key lock)")?;
2817                     (key_id_guard, tx)
2818                 }
2819                 Some(l) => (l, tx),
2820             },
2821             Some(key_id_guard) => (key_id_guard, tx),
2822         };
2823 
2824         let key_entry = Self::load_key_components(&tx, load_bits, key_id_guard.id())
2825             .context("In load_key_entry.")?;
2826 
2827         tx.commit().context("In load_key_entry: Failed to commit transaction.")?;
2828 
2829         Ok((key_id_guard, key_entry))
2830     }
2831 
mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool>2832     fn mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool> {
2833         let updated = tx
2834             .execute("DELETE FROM persistent.keyentry WHERE id = ?;", params![key_id])
2835             .context("Trying to delete keyentry.")?;
2836         tx.execute("DELETE FROM persistent.keymetadata WHERE keyentryid = ?;", params![key_id])
2837             .context("Trying to delete keymetadata.")?;
2838         tx.execute("DELETE FROM persistent.keyparameter WHERE keyentryid = ?;", params![key_id])
2839             .context("Trying to delete keyparameters.")?;
2840         tx.execute("DELETE FROM persistent.grant WHERE keyentryid = ?;", params![key_id])
2841             .context("Trying to delete grants.")?;
2842         Ok(updated != 0)
2843     }
2844 
2845     /// Marks the given key as unreferenced and removes all of the grants to this key.
2846     /// Returns Ok(true) if a key was marked unreferenced as a hint for the garbage collector.
unbind_key( &mut self, key: &KeyDescriptor, key_type: KeyType, caller_uid: u32, check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, ) -> Result<()>2847     pub fn unbind_key(
2848         &mut self,
2849         key: &KeyDescriptor,
2850         key_type: KeyType,
2851         caller_uid: u32,
2852         check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
2853     ) -> Result<()> {
2854         let _wp = wd::watch_millis("KeystoreDB::unbind_key", 500);
2855 
2856         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2857             let (key_id, access_key_descriptor, access_vector) =
2858                 Self::load_access_tuple(tx, key, key_type, caller_uid)
2859                     .context("Trying to get access tuple.")?;
2860 
2861             // Perform access control. It is vital that we return here if the permission is denied.
2862             // So do not touch that '?' at the end.
2863             check_permission(&access_key_descriptor, access_vector)
2864                 .context("While checking permission.")?;
2865 
2866             Self::mark_unreferenced(tx, key_id)
2867                 .map(|need_gc| (need_gc, ()))
2868                 .context("Trying to mark the key unreferenced.")
2869         })
2870         .context("In unbind_key.")
2871     }
2872 
get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid>2873     fn get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid> {
2874         tx.query_row(
2875             "SELECT km_uuid FROM persistent.keyentry WHERE id = ?",
2876             params![key_id],
2877             |row| row.get(0),
2878         )
2879         .context("In get_key_km_uuid.")
2880     }
2881 
2882     /// Delete all artifacts belonging to the namespace given by the domain-namespace tuple.
2883     /// This leaves all of the blob entries orphaned for subsequent garbage collection.
unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()>2884     pub fn unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()> {
2885         let _wp = wd::watch_millis("KeystoreDB::unbind_keys_for_namespace", 500);
2886 
2887         if !(domain == Domain::APP || domain == Domain::SELINUX) {
2888             return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
2889                 .context("In unbind_keys_for_namespace.");
2890         }
2891         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2892             tx.execute(
2893                 "DELETE FROM persistent.keymetadata
2894                 WHERE keyentryid IN (
2895                     SELECT id FROM persistent.keyentry
2896                     WHERE domain = ? AND namespace = ? AND (key_type = ? OR key_type = ?)
2897                 );",
2898                 params![domain.0, namespace, KeyType::Client, KeyType::Attestation],
2899             )
2900             .context("Trying to delete keymetadata.")?;
2901             tx.execute(
2902                 "DELETE FROM persistent.keyparameter
2903                 WHERE keyentryid IN (
2904                     SELECT id FROM persistent.keyentry
2905                     WHERE domain = ? AND namespace = ? AND (key_type = ? OR key_type = ?)
2906                 );",
2907                 params![domain.0, namespace, KeyType::Client, KeyType::Attestation],
2908             )
2909             .context("Trying to delete keyparameters.")?;
2910             tx.execute(
2911                 "DELETE FROM persistent.grant
2912                 WHERE keyentryid IN (
2913                     SELECT id FROM persistent.keyentry
2914                     WHERE domain = ? AND namespace = ? AND (key_type = ? OR key_type = ?)
2915                 );",
2916                 params![domain.0, namespace, KeyType::Client, KeyType::Attestation],
2917             )
2918             .context("Trying to delete grants.")?;
2919             tx.execute(
2920                 "DELETE FROM persistent.keyentry
2921                  WHERE domain = ? AND namespace = ? AND (key_type = ? OR key_type = ?);",
2922                 params![domain.0, namespace, KeyType::Client, KeyType::Attestation],
2923             )
2924             .context("Trying to delete keyentry.")?;
2925             Ok(()).need_gc()
2926         })
2927         .context("In unbind_keys_for_namespace")
2928     }
2929 
cleanup_unreferenced(tx: &Transaction) -> Result<()>2930     fn cleanup_unreferenced(tx: &Transaction) -> Result<()> {
2931         let _wp = wd::watch_millis("KeystoreDB::cleanup_unreferenced", 500);
2932         {
2933             tx.execute(
2934                 "DELETE FROM persistent.keymetadata
2935             WHERE keyentryid IN (
2936                 SELECT id FROM persistent.keyentry
2937                 WHERE state = ?
2938             );",
2939                 params![KeyLifeCycle::Unreferenced],
2940             )
2941             .context("Trying to delete keymetadata.")?;
2942             tx.execute(
2943                 "DELETE FROM persistent.keyparameter
2944             WHERE keyentryid IN (
2945                 SELECT id FROM persistent.keyentry
2946                 WHERE state = ?
2947             );",
2948                 params![KeyLifeCycle::Unreferenced],
2949             )
2950             .context("Trying to delete keyparameters.")?;
2951             tx.execute(
2952                 "DELETE FROM persistent.grant
2953             WHERE keyentryid IN (
2954                 SELECT id FROM persistent.keyentry
2955                 WHERE state = ?
2956             );",
2957                 params![KeyLifeCycle::Unreferenced],
2958             )
2959             .context("Trying to delete grants.")?;
2960             tx.execute(
2961                 "DELETE FROM persistent.keyentry
2962                 WHERE state = ?;",
2963                 params![KeyLifeCycle::Unreferenced],
2964             )
2965             .context("Trying to delete keyentry.")?;
2966             Result::<()>::Ok(())
2967         }
2968         .context("In cleanup_unreferenced")
2969     }
2970 
2971     /// Delete the keys created on behalf of the user, denoted by the user id.
2972     /// Delete all the keys unless 'keep_non_super_encrypted_keys' set to true.
2973     /// Returned boolean is to hint the garbage collector to delete the unbound keys.
2974     /// The caller of this function should notify the gc if the returned value is true.
unbind_keys_for_user( &mut self, user_id: u32, keep_non_super_encrypted_keys: bool, ) -> Result<()>2975     pub fn unbind_keys_for_user(
2976         &mut self,
2977         user_id: u32,
2978         keep_non_super_encrypted_keys: bool,
2979     ) -> Result<()> {
2980         let _wp = wd::watch_millis("KeystoreDB::unbind_keys_for_user", 500);
2981 
2982         self.with_transaction(TransactionBehavior::Immediate, |tx| {
2983             let mut stmt = tx
2984                 .prepare(&format!(
2985                     "SELECT id from persistent.keyentry
2986                      WHERE (
2987                          key_type = ?
2988                          AND domain = ?
2989                          AND cast ( (namespace/{aid_user_offset}) as int) = ?
2990                          AND state = ?
2991                      ) OR (
2992                          key_type = ?
2993                          AND namespace = ?
2994                          AND state = ?
2995                      );",
2996                     aid_user_offset = AID_USER_OFFSET
2997                 ))
2998                 .context(concat!(
2999                     "In unbind_keys_for_user. ",
3000                     "Failed to prepare the query to find the keys created by apps."
3001                 ))?;
3002 
3003             let mut rows = stmt
3004                 .query(params![
3005                     // WHERE client key:
3006                     KeyType::Client,
3007                     Domain::APP.0 as u32,
3008                     user_id,
3009                     KeyLifeCycle::Live,
3010                     // OR super key:
3011                     KeyType::Super,
3012                     user_id,
3013                     KeyLifeCycle::Live
3014                 ])
3015                 .context("In unbind_keys_for_user. Failed to query the keys created by apps.")?;
3016 
3017             let mut key_ids: Vec<i64> = Vec::new();
3018             db_utils::with_rows_extract_all(&mut rows, |row| {
3019                 key_ids
3020                     .push(row.get(0).context("Failed to read key id of a key created by an app.")?);
3021                 Ok(())
3022             })
3023             .context("In unbind_keys_for_user.")?;
3024 
3025             let mut notify_gc = false;
3026             for key_id in key_ids {
3027                 if keep_non_super_encrypted_keys {
3028                     // Load metadata and filter out non-super-encrypted keys.
3029                     if let (_, Some((_, blob_metadata)), _, _) =
3030                         Self::load_blob_components(key_id, KeyEntryLoadBits::KM, tx)
3031                             .context("In unbind_keys_for_user: Trying to load blob info.")?
3032                     {
3033                         if blob_metadata.encrypted_by().is_none() {
3034                             continue;
3035                         }
3036                     }
3037                 }
3038                 notify_gc = Self::mark_unreferenced(tx, key_id)
3039                     .context("In unbind_keys_for_user.")?
3040                     || notify_gc;
3041             }
3042             Ok(()).do_gc(notify_gc)
3043         })
3044         .context("In unbind_keys_for_user.")
3045     }
3046 
load_key_components( tx: &Transaction, load_bits: KeyEntryLoadBits, key_id: i64, ) -> Result<KeyEntry>3047     fn load_key_components(
3048         tx: &Transaction,
3049         load_bits: KeyEntryLoadBits,
3050         key_id: i64,
3051     ) -> Result<KeyEntry> {
3052         let metadata = KeyMetaData::load_from_db(key_id, tx).context("In load_key_components.")?;
3053 
3054         let (has_km_blob, key_blob_info, cert_blob, cert_chain_blob) =
3055             Self::load_blob_components(key_id, load_bits, tx).context("In load_key_components.")?;
3056 
3057         let parameters = Self::load_key_parameters(key_id, tx)
3058             .context("In load_key_components: Trying to load key parameters.")?;
3059 
3060         let km_uuid = Self::get_key_km_uuid(tx, key_id)
3061             .context("In load_key_components: Trying to get KM uuid.")?;
3062 
3063         Ok(KeyEntry {
3064             id: key_id,
3065             key_blob_info,
3066             cert: cert_blob,
3067             cert_chain: cert_chain_blob,
3068             km_uuid,
3069             parameters,
3070             metadata,
3071             pure_cert: !has_km_blob,
3072         })
3073     }
3074 
3075     /// Returns a list of KeyDescriptors in the selected domain/namespace.
3076     /// The key descriptors will have the domain, nspace, and alias field set.
3077     /// Domain must be APP or SELINUX, the caller must make sure of that.
list( &mut self, domain: Domain, namespace: i64, key_type: KeyType, ) -> Result<Vec<KeyDescriptor>>3078     pub fn list(
3079         &mut self,
3080         domain: Domain,
3081         namespace: i64,
3082         key_type: KeyType,
3083     ) -> Result<Vec<KeyDescriptor>> {
3084         let _wp = wd::watch_millis("KeystoreDB::list", 500);
3085 
3086         self.with_transaction(TransactionBehavior::Deferred, |tx| {
3087             let mut stmt = tx
3088                 .prepare(
3089                     "SELECT alias FROM persistent.keyentry
3090                      WHERE domain = ?
3091                      AND namespace = ?
3092                      AND alias IS NOT NULL
3093                      AND state = ?
3094                      AND key_type = ?;",
3095                 )
3096                 .context("In list: Failed to prepare.")?;
3097 
3098             let mut rows = stmt
3099                 .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type])
3100                 .context("In list: Failed to query.")?;
3101 
3102             let mut descriptors: Vec<KeyDescriptor> = Vec::new();
3103             db_utils::with_rows_extract_all(&mut rows, |row| {
3104                 descriptors.push(KeyDescriptor {
3105                     domain,
3106                     nspace: namespace,
3107                     alias: Some(row.get(0).context("Trying to extract alias.")?),
3108                     blob: None,
3109                 });
3110                 Ok(())
3111             })
3112             .context("In list: Failed to extract rows.")?;
3113             Ok(descriptors).no_gc()
3114         })
3115     }
3116 
3117     /// Adds a grant to the grant table.
3118     /// Like `load_key_entry` this function loads the access tuple before
3119     /// it uses the callback for a permission check. Upon success,
3120     /// it inserts the `grantee_uid`, `key_id`, and `access_vector` into the
3121     /// grant table. The new row will have a randomized id, which is used as
3122     /// grant id in the namespace field of the resulting KeyDescriptor.
grant( &mut self, key: &KeyDescriptor, caller_uid: u32, grantee_uid: u32, access_vector: KeyPermSet, check_permission: impl Fn(&KeyDescriptor, &KeyPermSet) -> Result<()>, ) -> Result<KeyDescriptor>3123     pub fn grant(
3124         &mut self,
3125         key: &KeyDescriptor,
3126         caller_uid: u32,
3127         grantee_uid: u32,
3128         access_vector: KeyPermSet,
3129         check_permission: impl Fn(&KeyDescriptor, &KeyPermSet) -> Result<()>,
3130     ) -> Result<KeyDescriptor> {
3131         let _wp = wd::watch_millis("KeystoreDB::grant", 500);
3132 
3133         self.with_transaction(TransactionBehavior::Immediate, |tx| {
3134             // Load the key_id and complete the access control tuple.
3135             // We ignore the access vector here because grants cannot be granted.
3136             // The access vector returned here expresses the permissions the
3137             // grantee has if key.domain == Domain::GRANT. But this vector
3138             // cannot include the grant permission by design, so there is no way the
3139             // subsequent permission check can pass.
3140             // We could check key.domain == Domain::GRANT and fail early.
3141             // But even if we load the access tuple by grant here, the permission
3142             // check denies the attempt to create a grant by grant descriptor.
3143             let (key_id, access_key_descriptor, _) =
3144                 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid)
3145                     .context("In grant")?;
3146 
3147             // Perform access control. It is vital that we return here if the permission
3148             // was denied. So do not touch that '?' at the end of the line.
3149             // This permission check checks if the caller has the grant permission
3150             // for the given key and in addition to all of the permissions
3151             // expressed in `access_vector`.
3152             check_permission(&access_key_descriptor, &access_vector)
3153                 .context("In grant: check_permission failed.")?;
3154 
3155             let grant_id = if let Some(grant_id) = tx
3156                 .query_row(
3157                     "SELECT id FROM persistent.grant
3158                 WHERE keyentryid = ? AND grantee = ?;",
3159                     params![key_id, grantee_uid],
3160                     |row| row.get(0),
3161                 )
3162                 .optional()
3163                 .context("In grant: Failed get optional existing grant id.")?
3164             {
3165                 tx.execute(
3166                     "UPDATE persistent.grant
3167                     SET access_vector = ?
3168                     WHERE id = ?;",
3169                     params![i32::from(access_vector), grant_id],
3170                 )
3171                 .context("In grant: Failed to update existing grant.")?;
3172                 grant_id
3173             } else {
3174                 Self::insert_with_retry(|id| {
3175                     tx.execute(
3176                         "INSERT INTO persistent.grant (id, grantee, keyentryid, access_vector)
3177                         VALUES (?, ?, ?, ?);",
3178                         params![id, grantee_uid, key_id, i32::from(access_vector)],
3179                     )
3180                 })
3181                 .context("In grant")?
3182             };
3183 
3184             Ok(KeyDescriptor { domain: Domain::GRANT, nspace: grant_id, alias: None, blob: None })
3185                 .no_gc()
3186         })
3187     }
3188 
3189     /// This function checks permissions like `grant` and `load_key_entry`
3190     /// before removing a grant from the grant table.
ungrant( &mut self, key: &KeyDescriptor, caller_uid: u32, grantee_uid: u32, check_permission: impl Fn(&KeyDescriptor) -> Result<()>, ) -> Result<()>3191     pub fn ungrant(
3192         &mut self,
3193         key: &KeyDescriptor,
3194         caller_uid: u32,
3195         grantee_uid: u32,
3196         check_permission: impl Fn(&KeyDescriptor) -> Result<()>,
3197     ) -> Result<()> {
3198         let _wp = wd::watch_millis("KeystoreDB::ungrant", 500);
3199 
3200         self.with_transaction(TransactionBehavior::Immediate, |tx| {
3201             // Load the key_id and complete the access control tuple.
3202             // We ignore the access vector here because grants cannot be granted.
3203             let (key_id, access_key_descriptor, _) =
3204                 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid)
3205                     .context("In ungrant.")?;
3206 
3207             // Perform access control. We must return here if the permission
3208             // was denied. So do not touch the '?' at the end of this line.
3209             check_permission(&access_key_descriptor)
3210                 .context("In grant: check_permission failed.")?;
3211 
3212             tx.execute(
3213                 "DELETE FROM persistent.grant
3214                 WHERE keyentryid = ? AND grantee = ?;",
3215                 params![key_id, grantee_uid],
3216             )
3217             .context("Failed to delete grant.")?;
3218 
3219             Ok(()).no_gc()
3220         })
3221     }
3222 
3223     // Generates a random id and passes it to the given function, which will
3224     // try to insert it into a database.  If that insertion fails, retry;
3225     // otherwise return the id.
insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64>3226     fn insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64> {
3227         loop {
3228             let newid: i64 = match random() {
3229                 Self::UNASSIGNED_KEY_ID => continue, // UNASSIGNED_KEY_ID cannot be assigned.
3230                 i => i,
3231             };
3232             match inserter(newid) {
3233                 // If the id already existed, try again.
3234                 Err(rusqlite::Error::SqliteFailure(
3235                     libsqlite3_sys::Error {
3236                         code: libsqlite3_sys::ErrorCode::ConstraintViolation,
3237                         extended_code: libsqlite3_sys::SQLITE_CONSTRAINT_UNIQUE,
3238                     },
3239                     _,
3240                 )) => (),
3241                 Err(e) => {
3242                     return Err(e).context("In insert_with_retry: failed to insert into database.")
3243                 }
3244                 _ => return Ok(newid),
3245             }
3246         }
3247     }
3248 
3249     /// Insert or replace the auth token based on (user_id, auth_id, auth_type)
insert_auth_token(&mut self, auth_token: &HardwareAuthToken)3250     pub fn insert_auth_token(&mut self, auth_token: &HardwareAuthToken) {
3251         self.perboot.insert_auth_token_entry(AuthTokenEntry::new(
3252             auth_token.clone(),
3253             MonotonicRawTime::now(),
3254         ))
3255     }
3256 
3257     /// Find the newest auth token matching the given predicate.
find_auth_token_entry<F>(&self, p: F) -> Option<(AuthTokenEntry, MonotonicRawTime)> where F: Fn(&AuthTokenEntry) -> bool,3258     pub fn find_auth_token_entry<F>(&self, p: F) -> Option<(AuthTokenEntry, MonotonicRawTime)>
3259     where
3260         F: Fn(&AuthTokenEntry) -> bool,
3261     {
3262         self.perboot.find_auth_token_entry(p).map(|entry| (entry, self.get_last_off_body()))
3263     }
3264 
3265     /// Insert last_off_body into the metadata table at the initialization of auth token table
insert_last_off_body(&self, last_off_body: MonotonicRawTime)3266     pub fn insert_last_off_body(&self, last_off_body: MonotonicRawTime) {
3267         self.perboot.set_last_off_body(last_off_body)
3268     }
3269 
3270     /// Update last_off_body when on_device_off_body is called
update_last_off_body(&self, last_off_body: MonotonicRawTime)3271     pub fn update_last_off_body(&self, last_off_body: MonotonicRawTime) {
3272         self.perboot.set_last_off_body(last_off_body)
3273     }
3274 
3275     /// Get last_off_body time when finding auth tokens
get_last_off_body(&self) -> MonotonicRawTime3276     fn get_last_off_body(&self) -> MonotonicRawTime {
3277         self.perboot.get_last_off_body()
3278     }
3279 
3280     /// Load descriptor of a key by key id
load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>>3281     pub fn load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>> {
3282         let _wp = wd::watch_millis("KeystoreDB::load_key_descriptor", 500);
3283 
3284         self.with_transaction(TransactionBehavior::Deferred, |tx| {
3285             tx.query_row(
3286                 "SELECT domain, namespace, alias FROM persistent.keyentry WHERE id = ?;",
3287                 params![key_id],
3288                 |row| {
3289                     Ok(KeyDescriptor {
3290                         domain: Domain(row.get(0)?),
3291                         nspace: row.get(1)?,
3292                         alias: row.get(2)?,
3293                         blob: None,
3294                     })
3295                 },
3296             )
3297             .optional()
3298             .context("Trying to load key descriptor")
3299             .no_gc()
3300         })
3301         .context("In load_key_descriptor.")
3302     }
3303 }
3304 
3305 #[cfg(test)]
3306 pub mod tests {
3307 
3308     use super::*;
3309     use crate::key_parameter::{
3310         Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyOrigin, KeyParameter,
3311         KeyParameterValue, KeyPurpose, PaddingMode, SecurityLevel,
3312     };
3313     use crate::key_perm_set;
3314     use crate::permission::{KeyPerm, KeyPermSet};
3315     use crate::super_key::{SuperKeyManager, USER_SUPER_KEY, SuperEncryptionAlgorithm, SuperKeyType};
3316     use keystore2_test_utils::TempDir;
3317     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
3318         HardwareAuthToken::HardwareAuthToken,
3319         HardwareAuthenticatorType::HardwareAuthenticatorType as kmhw_authenticator_type,
3320     };
3321     use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
3322         Timestamp::Timestamp,
3323     };
3324     use rusqlite::NO_PARAMS;
3325     use rusqlite::TransactionBehavior;
3326     use std::cell::RefCell;
3327     use std::collections::BTreeMap;
3328     use std::fmt::Write;
3329     use std::sync::atomic::{AtomicU8, Ordering};
3330     use std::sync::{Arc, RwLock};
3331     use std::thread;
3332     use std::time::{Duration, SystemTime};
3333     use crate::utils::AesGcm;
3334     #[cfg(disabled)]
3335     use std::time::Instant;
3336 
new_test_db() -> Result<KeystoreDB>3337     pub fn new_test_db() -> Result<KeystoreDB> {
3338         let conn = KeystoreDB::make_connection("file::memory:")?;
3339 
3340         let mut db = KeystoreDB { conn, gc: None, perboot: Arc::new(perboot::PerbootDB::new()) };
3341         db.with_transaction(TransactionBehavior::Immediate, |tx| {
3342             KeystoreDB::init_tables(tx).context("Failed to initialize tables.").no_gc()
3343         })?;
3344         Ok(db)
3345     }
3346 
new_test_db_with_gc<F>(path: &Path, cb: F) -> Result<KeystoreDB> where F: Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static,3347     fn new_test_db_with_gc<F>(path: &Path, cb: F) -> Result<KeystoreDB>
3348     where
3349         F: Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static,
3350     {
3351         let super_key: Arc<RwLock<SuperKeyManager>> = Default::default();
3352 
3353         let gc_db = KeystoreDB::new(path, None).expect("Failed to open test gc db_connection.");
3354         let gc = Gc::new_init_with(Default::default(), move || (Box::new(cb), gc_db, super_key));
3355 
3356         KeystoreDB::new(path, Some(Arc::new(gc)))
3357     }
3358 
rebind_alias( db: &mut KeystoreDB, newid: &KeyIdGuard, alias: &str, domain: Domain, namespace: i64, ) -> Result<bool>3359     fn rebind_alias(
3360         db: &mut KeystoreDB,
3361         newid: &KeyIdGuard,
3362         alias: &str,
3363         domain: Domain,
3364         namespace: i64,
3365     ) -> Result<bool> {
3366         db.with_transaction(TransactionBehavior::Immediate, |tx| {
3367             KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace, KeyType::Client).no_gc()
3368         })
3369         .context("In rebind_alias.")
3370     }
3371 
3372     #[test]
datetime() -> Result<()>3373     fn datetime() -> Result<()> {
3374         let conn = Connection::open_in_memory()?;
3375         conn.execute("CREATE TABLE test (ts DATETIME);", NO_PARAMS)?;
3376         let now = SystemTime::now();
3377         let duration = Duration::from_secs(1000);
3378         let then = now.checked_sub(duration).unwrap();
3379         let soon = now.checked_add(duration).unwrap();
3380         conn.execute(
3381             "INSERT INTO test (ts) VALUES (?), (?), (?);",
3382             params![DateTime::try_from(now)?, DateTime::try_from(then)?, DateTime::try_from(soon)?],
3383         )?;
3384         let mut stmt = conn.prepare("SELECT ts FROM test ORDER BY ts ASC;")?;
3385         let mut rows = stmt.query(NO_PARAMS)?;
3386         assert_eq!(DateTime::try_from(then)?, rows.next()?.unwrap().get(0)?);
3387         assert_eq!(DateTime::try_from(now)?, rows.next()?.unwrap().get(0)?);
3388         assert_eq!(DateTime::try_from(soon)?, rows.next()?.unwrap().get(0)?);
3389         assert!(rows.next()?.is_none());
3390         assert!(DateTime::try_from(then)? < DateTime::try_from(now)?);
3391         assert!(DateTime::try_from(then)? < DateTime::try_from(soon)?);
3392         assert!(DateTime::try_from(now)? < DateTime::try_from(soon)?);
3393         Ok(())
3394     }
3395 
3396     // Ensure that we're using the "injected" random function, not the real one.
3397     #[test]
test_mocked_random()3398     fn test_mocked_random() {
3399         let rand1 = random();
3400         let rand2 = random();
3401         let rand3 = random();
3402         if rand1 == rand2 {
3403             assert_eq!(rand2 + 1, rand3);
3404         } else {
3405             assert_eq!(rand1 + 1, rand2);
3406             assert_eq!(rand2, rand3);
3407         }
3408     }
3409 
3410     // Test that we have the correct tables.
3411     #[test]
test_tables() -> Result<()>3412     fn test_tables() -> Result<()> {
3413         let db = new_test_db()?;
3414         let tables = db
3415             .conn
3416             .prepare("SELECT name from persistent.sqlite_master WHERE type='table' ORDER BY name;")?
3417             .query_map(params![], |row| row.get(0))?
3418             .collect::<rusqlite::Result<Vec<String>>>()?;
3419         assert_eq!(tables.len(), 6);
3420         assert_eq!(tables[0], "blobentry");
3421         assert_eq!(tables[1], "blobmetadata");
3422         assert_eq!(tables[2], "grant");
3423         assert_eq!(tables[3], "keyentry");
3424         assert_eq!(tables[4], "keymetadata");
3425         assert_eq!(tables[5], "keyparameter");
3426         Ok(())
3427     }
3428 
3429     #[test]
test_auth_token_table_invariant() -> Result<()>3430     fn test_auth_token_table_invariant() -> Result<()> {
3431         let mut db = new_test_db()?;
3432         let auth_token1 = HardwareAuthToken {
3433             challenge: i64::MAX,
3434             userId: 200,
3435             authenticatorId: 200,
3436             authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
3437             timestamp: Timestamp { milliSeconds: 500 },
3438             mac: String::from("mac").into_bytes(),
3439         };
3440         db.insert_auth_token(&auth_token1);
3441         let auth_tokens_returned = get_auth_tokens(&db);
3442         assert_eq!(auth_tokens_returned.len(), 1);
3443 
3444         // insert another auth token with the same values for the columns in the UNIQUE constraint
3445         // of the auth token table and different value for timestamp
3446         let auth_token2 = HardwareAuthToken {
3447             challenge: i64::MAX,
3448             userId: 200,
3449             authenticatorId: 200,
3450             authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
3451             timestamp: Timestamp { milliSeconds: 600 },
3452             mac: String::from("mac").into_bytes(),
3453         };
3454 
3455         db.insert_auth_token(&auth_token2);
3456         let mut auth_tokens_returned = get_auth_tokens(&db);
3457         assert_eq!(auth_tokens_returned.len(), 1);
3458 
3459         if let Some(auth_token) = auth_tokens_returned.pop() {
3460             assert_eq!(auth_token.auth_token.timestamp.milliSeconds, 600);
3461         }
3462 
3463         // insert another auth token with the different values for the columns in the UNIQUE
3464         // constraint of the auth token table
3465         let auth_token3 = HardwareAuthToken {
3466             challenge: i64::MAX,
3467             userId: 201,
3468             authenticatorId: 200,
3469             authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
3470             timestamp: Timestamp { milliSeconds: 600 },
3471             mac: String::from("mac").into_bytes(),
3472         };
3473 
3474         db.insert_auth_token(&auth_token3);
3475         let auth_tokens_returned = get_auth_tokens(&db);
3476         assert_eq!(auth_tokens_returned.len(), 2);
3477 
3478         Ok(())
3479     }
3480 
3481     // utility function for test_auth_token_table_invariant()
get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry>3482     fn get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry> {
3483         db.perboot.get_all_auth_token_entries()
3484     }
3485 
3486     #[test]
test_persistence_for_files() -> Result<()>3487     fn test_persistence_for_files() -> Result<()> {
3488         let temp_dir = TempDir::new("persistent_db_test")?;
3489         let mut db = KeystoreDB::new(temp_dir.path(), None)?;
3490 
3491         db.create_key_entry(&Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
3492         let entries = get_keyentry(&db)?;
3493         assert_eq!(entries.len(), 1);
3494 
3495         let db = KeystoreDB::new(temp_dir.path(), None)?;
3496 
3497         let entries_new = get_keyentry(&db)?;
3498         assert_eq!(entries, entries_new);
3499         Ok(())
3500     }
3501 
3502     #[test]
test_create_key_entry() -> Result<()>3503     fn test_create_key_entry() -> Result<()> {
3504         fn extractor(ke: &KeyEntryRow) -> (Domain, i64, Option<&str>, Uuid) {
3505             (ke.domain.unwrap(), ke.namespace.unwrap(), ke.alias.as_deref(), ke.km_uuid.unwrap())
3506         }
3507 
3508         let mut db = new_test_db()?;
3509 
3510         db.create_key_entry(&Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
3511         db.create_key_entry(&Domain::SELINUX, &101, KeyType::Client, &KEYSTORE_UUID)?;
3512 
3513         let entries = get_keyentry(&db)?;
3514         assert_eq!(entries.len(), 2);
3515         assert_eq!(extractor(&entries[0]), (Domain::APP, 100, None, KEYSTORE_UUID));
3516         assert_eq!(extractor(&entries[1]), (Domain::SELINUX, 101, None, KEYSTORE_UUID));
3517 
3518         // Test that we must pass in a valid Domain.
3519         check_result_is_error_containing_string(
3520             db.create_key_entry(&Domain::GRANT, &102, KeyType::Client, &KEYSTORE_UUID),
3521             "Domain Domain(1) must be either App or SELinux.",
3522         );
3523         check_result_is_error_containing_string(
3524             db.create_key_entry(&Domain::BLOB, &103, KeyType::Client, &KEYSTORE_UUID),
3525             "Domain Domain(3) must be either App or SELinux.",
3526         );
3527         check_result_is_error_containing_string(
3528             db.create_key_entry(&Domain::KEY_ID, &104, KeyType::Client, &KEYSTORE_UUID),
3529             "Domain Domain(4) must be either App or SELinux.",
3530         );
3531 
3532         Ok(())
3533     }
3534 
3535     #[test]
test_add_unsigned_key() -> Result<()>3536     fn test_add_unsigned_key() -> Result<()> {
3537         let mut db = new_test_db()?;
3538         let public_key: Vec<u8> = vec![0x01, 0x02, 0x03];
3539         let private_key: Vec<u8> = vec![0x04, 0x05, 0x06];
3540         let raw_public_key: Vec<u8> = vec![0x07, 0x08, 0x09];
3541         db.create_attestation_key_entry(
3542             &public_key,
3543             &raw_public_key,
3544             &private_key,
3545             &KEYSTORE_UUID,
3546         )?;
3547         let keys = db.fetch_unsigned_attestation_keys(5, &KEYSTORE_UUID)?;
3548         assert_eq!(keys.len(), 1);
3549         assert_eq!(keys[0], public_key);
3550         Ok(())
3551     }
3552 
3553     #[test]
test_store_signed_attestation_certificate_chain() -> Result<()>3554     fn test_store_signed_attestation_certificate_chain() -> Result<()> {
3555         let mut db = new_test_db()?;
3556         let expiration_date: i64 =
3557             SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
3558                 + EXPIRATION_BUFFER_MS
3559                 + 10000;
3560         let namespace: i64 = 30;
3561         let base_byte: u8 = 1;
3562         let loaded_values =
3563             load_attestation_key_pool(&mut db, expiration_date, namespace, base_byte)?;
3564         let chain =
3565             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
3566         assert!(chain.is_some());
3567         let (_, cert_chain) = chain.unwrap();
3568         assert_eq!(cert_chain.private_key.to_vec(), loaded_values.priv_key);
3569         assert_eq!(cert_chain.batch_cert, loaded_values.batch_cert);
3570         assert_eq!(cert_chain.cert_chain, loaded_values.cert_chain);
3571         Ok(())
3572     }
3573 
3574     #[test]
test_get_attestation_pool_status() -> Result<()>3575     fn test_get_attestation_pool_status() -> Result<()> {
3576         let mut db = new_test_db()?;
3577         let namespace: i64 = 30;
3578         load_attestation_key_pool(
3579             &mut db, 10, /* expiration */
3580             namespace, 0x01, /* base_byte */
3581         )?;
3582         load_attestation_key_pool(&mut db, 20 /* expiration */, namespace + 1, 0x02)?;
3583         load_attestation_key_pool(&mut db, 40 /* expiration */, namespace + 2, 0x03)?;
3584         let mut status = db.get_attestation_pool_status(9 /* expiration */, &KEYSTORE_UUID)?;
3585         assert_eq!(status.expiring, 0);
3586         assert_eq!(status.attested, 3);
3587         assert_eq!(status.unassigned, 0);
3588         assert_eq!(status.total, 3);
3589         assert_eq!(
3590             db.get_attestation_pool_status(15 /* expiration */, &KEYSTORE_UUID)?.expiring,
3591             1
3592         );
3593         assert_eq!(
3594             db.get_attestation_pool_status(25 /* expiration */, &KEYSTORE_UUID)?.expiring,
3595             2
3596         );
3597         assert_eq!(
3598             db.get_attestation_pool_status(60 /* expiration */, &KEYSTORE_UUID)?.expiring,
3599             3
3600         );
3601         let public_key: Vec<u8> = vec![0x01, 0x02, 0x03];
3602         let private_key: Vec<u8> = vec![0x04, 0x05, 0x06];
3603         let raw_public_key: Vec<u8> = vec![0x07, 0x08, 0x09];
3604         let cert_chain: Vec<u8> = vec![0x0a, 0x0b, 0x0c];
3605         let batch_cert: Vec<u8> = vec![0x0d, 0x0e, 0x0f];
3606         db.create_attestation_key_entry(
3607             &public_key,
3608             &raw_public_key,
3609             &private_key,
3610             &KEYSTORE_UUID,
3611         )?;
3612         status = db.get_attestation_pool_status(0 /* expiration */, &KEYSTORE_UUID)?;
3613         assert_eq!(status.attested, 3);
3614         assert_eq!(status.unassigned, 0);
3615         assert_eq!(status.total, 4);
3616         db.store_signed_attestation_certificate_chain(
3617             &raw_public_key,
3618             &batch_cert,
3619             &cert_chain,
3620             20,
3621             &KEYSTORE_UUID,
3622         )?;
3623         status = db.get_attestation_pool_status(0 /* expiration */, &KEYSTORE_UUID)?;
3624         assert_eq!(status.attested, 4);
3625         assert_eq!(status.unassigned, 1);
3626         assert_eq!(status.total, 4);
3627         Ok(())
3628     }
3629 
3630     #[test]
test_remove_expired_certs() -> Result<()>3631     fn test_remove_expired_certs() -> Result<()> {
3632         let temp_dir =
3633             TempDir::new("test_remove_expired_certs_").expect("Failed to create temp dir.");
3634         let mut db = new_test_db_with_gc(temp_dir.path(), |_, _| Ok(()))?;
3635         let expiration_date: i64 =
3636             SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
3637                 + EXPIRATION_BUFFER_MS
3638                 + 10000;
3639         let namespace: i64 = 30;
3640         let namespace_del1: i64 = 45;
3641         let namespace_del2: i64 = 60;
3642         let entry_values = load_attestation_key_pool(
3643             &mut db,
3644             expiration_date,
3645             namespace,
3646             0x01, /* base_byte */
3647         )?;
3648         load_attestation_key_pool(&mut db, 45, namespace_del1, 0x02)?;
3649         load_attestation_key_pool(&mut db, expiration_date - 10001, namespace_del2, 0x03)?;
3650 
3651         let blob_entry_row_count: u32 = db
3652             .conn
3653             .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
3654             .expect("Failed to get blob entry row count.");
3655         // We expect 9 rows here because there are three blobs per attestation key, i.e.,
3656         // one key, one certificate chain, and one certificate.
3657         assert_eq!(blob_entry_row_count, 9);
3658 
3659         assert_eq!(db.delete_expired_attestation_keys()?, 2);
3660 
3661         let mut cert_chain =
3662             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
3663         assert!(cert_chain.is_some());
3664         let (_, value) = cert_chain.unwrap();
3665         assert_eq!(entry_values.batch_cert, value.batch_cert);
3666         assert_eq!(entry_values.cert_chain, value.cert_chain);
3667         assert_eq!(entry_values.priv_key, value.private_key.to_vec());
3668 
3669         cert_chain = db.retrieve_attestation_key_and_cert_chain(
3670             Domain::APP,
3671             namespace_del1,
3672             &KEYSTORE_UUID,
3673         )?;
3674         assert!(cert_chain.is_none());
3675         cert_chain = db.retrieve_attestation_key_and_cert_chain(
3676             Domain::APP,
3677             namespace_del2,
3678             &KEYSTORE_UUID,
3679         )?;
3680         assert!(cert_chain.is_none());
3681 
3682         // Give the garbage collector half a second to catch up.
3683         std::thread::sleep(Duration::from_millis(500));
3684 
3685         let blob_entry_row_count: u32 = db
3686             .conn
3687             .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
3688             .expect("Failed to get blob entry row count.");
3689         // There shound be 3 blob entries left, because we deleted two of the attestation
3690         // key entries with three blobs each.
3691         assert_eq!(blob_entry_row_count, 3);
3692 
3693         Ok(())
3694     }
3695 
compare_rem_prov_values( expected: &RemoteProvValues, actual: Option<(KeyIdGuard, CertificateChain)>, )3696     fn compare_rem_prov_values(
3697         expected: &RemoteProvValues,
3698         actual: Option<(KeyIdGuard, CertificateChain)>,
3699     ) {
3700         assert!(actual.is_some());
3701         let (_, value) = actual.unwrap();
3702         assert_eq!(expected.batch_cert, value.batch_cert);
3703         assert_eq!(expected.cert_chain, value.cert_chain);
3704         assert_eq!(expected.priv_key, value.private_key.to_vec());
3705     }
3706 
3707     #[test]
test_dont_remove_valid_certs() -> Result<()>3708     fn test_dont_remove_valid_certs() -> Result<()> {
3709         let temp_dir =
3710             TempDir::new("test_remove_expired_certs_").expect("Failed to create temp dir.");
3711         let mut db = new_test_db_with_gc(temp_dir.path(), |_, _| Ok(()))?;
3712         let expiration_date: i64 =
3713             SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
3714                 + EXPIRATION_BUFFER_MS
3715                 + 10000;
3716         let namespace1: i64 = 30;
3717         let namespace2: i64 = 45;
3718         let namespace3: i64 = 60;
3719         let entry_values1 = load_attestation_key_pool(
3720             &mut db,
3721             expiration_date,
3722             namespace1,
3723             0x01, /* base_byte */
3724         )?;
3725         let entry_values2 =
3726             load_attestation_key_pool(&mut db, expiration_date + 40000, namespace2, 0x02)?;
3727         let entry_values3 =
3728             load_attestation_key_pool(&mut db, expiration_date - 9000, namespace3, 0x03)?;
3729 
3730         let blob_entry_row_count: u32 = db
3731             .conn
3732             .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
3733             .expect("Failed to get blob entry row count.");
3734         // We expect 9 rows here because there are three blobs per attestation key, i.e.,
3735         // one key, one certificate chain, and one certificate.
3736         assert_eq!(blob_entry_row_count, 9);
3737 
3738         let mut cert_chain =
3739             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace1, &KEYSTORE_UUID)?;
3740         compare_rem_prov_values(&entry_values1, cert_chain);
3741 
3742         cert_chain =
3743             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace2, &KEYSTORE_UUID)?;
3744         compare_rem_prov_values(&entry_values2, cert_chain);
3745 
3746         cert_chain =
3747             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace3, &KEYSTORE_UUID)?;
3748         compare_rem_prov_values(&entry_values3, cert_chain);
3749 
3750         // Give the garbage collector half a second to catch up.
3751         std::thread::sleep(Duration::from_millis(500));
3752 
3753         let blob_entry_row_count: u32 = db
3754             .conn
3755             .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
3756             .expect("Failed to get blob entry row count.");
3757         // There shound be 9 blob entries left, because all three keys are valid with
3758         // three blobs each.
3759         assert_eq!(blob_entry_row_count, 9);
3760 
3761         Ok(())
3762     }
3763     #[test]
test_delete_all_attestation_keys() -> Result<()>3764     fn test_delete_all_attestation_keys() -> Result<()> {
3765         let mut db = new_test_db()?;
3766         load_attestation_key_pool(&mut db, 45 /* expiration */, 1 /* namespace */, 0x02)?;
3767         load_attestation_key_pool(&mut db, 80 /* expiration */, 2 /* namespace */, 0x03)?;
3768         db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
3769         let result = db.delete_all_attestation_keys()?;
3770 
3771         // Give the garbage collector half a second to catch up.
3772         std::thread::sleep(Duration::from_millis(500));
3773 
3774         // Attestation keys should be deleted, and the regular key should remain.
3775         assert_eq!(result, 2);
3776 
3777         Ok(())
3778     }
3779 
3780     #[test]
test_rebind_alias() -> Result<()>3781     fn test_rebind_alias() -> Result<()> {
3782         fn extractor(
3783             ke: &KeyEntryRow,
3784         ) -> (Option<Domain>, Option<i64>, Option<&str>, Option<Uuid>) {
3785             (ke.domain, ke.namespace, ke.alias.as_deref(), ke.km_uuid)
3786         }
3787 
3788         let mut db = new_test_db()?;
3789         db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
3790         db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
3791         let entries = get_keyentry(&db)?;
3792         assert_eq!(entries.len(), 2);
3793         assert_eq!(
3794             extractor(&entries[0]),
3795             (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
3796         );
3797         assert_eq!(
3798             extractor(&entries[1]),
3799             (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
3800         );
3801 
3802         // Test that the first call to rebind_alias sets the alias.
3803         rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[0].id), "foo", Domain::APP, 42)?;
3804         let entries = get_keyentry(&db)?;
3805         assert_eq!(entries.len(), 2);
3806         assert_eq!(
3807             extractor(&entries[0]),
3808             (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
3809         );
3810         assert_eq!(
3811             extractor(&entries[1]),
3812             (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
3813         );
3814 
3815         // Test that the second call to rebind_alias also empties the old one.
3816         rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[1].id), "foo", Domain::APP, 42)?;
3817         let entries = get_keyentry(&db)?;
3818         assert_eq!(entries.len(), 2);
3819         assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
3820         assert_eq!(
3821             extractor(&entries[1]),
3822             (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
3823         );
3824 
3825         // Test that we must pass in a valid Domain.
3826         check_result_is_error_containing_string(
3827             rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::GRANT, 42),
3828             "Domain Domain(1) must be either App or SELinux.",
3829         );
3830         check_result_is_error_containing_string(
3831             rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::BLOB, 42),
3832             "Domain Domain(3) must be either App or SELinux.",
3833         );
3834         check_result_is_error_containing_string(
3835             rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::KEY_ID, 42),
3836             "Domain Domain(4) must be either App or SELinux.",
3837         );
3838 
3839         // Test that we correctly handle setting an alias for something that does not exist.
3840         check_result_is_error_containing_string(
3841             rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::SELINUX, 42),
3842             "Expected to update a single entry but instead updated 0",
3843         );
3844         // Test that we correctly abort the transaction in this case.
3845         let entries = get_keyentry(&db)?;
3846         assert_eq!(entries.len(), 2);
3847         assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
3848         assert_eq!(
3849             extractor(&entries[1]),
3850             (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
3851         );
3852 
3853         Ok(())
3854     }
3855 
3856     #[test]
test_grant_ungrant() -> Result<()>3857     fn test_grant_ungrant() -> Result<()> {
3858         const CALLER_UID: u32 = 15;
3859         const GRANTEE_UID: u32 = 12;
3860         const SELINUX_NAMESPACE: i64 = 7;
3861 
3862         let mut db = new_test_db()?;
3863         db.conn.execute(
3864             "INSERT INTO persistent.keyentry (id, key_type, domain, namespace, alias, state, km_uuid)
3865                 VALUES (1, 0, 0, 15, 'key', 1, ?), (2, 0, 2, 7, 'yek', 1, ?);",
3866             params![KEYSTORE_UUID, KEYSTORE_UUID],
3867         )?;
3868         let app_key = KeyDescriptor {
3869             domain: super::Domain::APP,
3870             nspace: 0,
3871             alias: Some("key".to_string()),
3872             blob: None,
3873         };
3874         const PVEC1: KeyPermSet = key_perm_set![KeyPerm::Use, KeyPerm::GetInfo];
3875         const PVEC2: KeyPermSet = key_perm_set![KeyPerm::Use];
3876 
3877         // Reset totally predictable random number generator in case we
3878         // are not the first test running on this thread.
3879         reset_random();
3880         let next_random = 0i64;
3881 
3882         let app_granted_key = db
3883             .grant(&app_key, CALLER_UID, GRANTEE_UID, PVEC1, |k, a| {
3884                 assert_eq!(*a, PVEC1);
3885                 assert_eq!(
3886                     *k,
3887                     KeyDescriptor {
3888                         domain: super::Domain::APP,
3889                         // namespace must be set to the caller_uid.
3890                         nspace: CALLER_UID as i64,
3891                         alias: Some("key".to_string()),
3892                         blob: None,
3893                     }
3894                 );
3895                 Ok(())
3896             })
3897             .unwrap();
3898 
3899         assert_eq!(
3900             app_granted_key,
3901             KeyDescriptor {
3902                 domain: super::Domain::GRANT,
3903                 // The grantid is next_random due to the mock random number generator.
3904                 nspace: next_random,
3905                 alias: None,
3906                 blob: None,
3907             }
3908         );
3909 
3910         let selinux_key = KeyDescriptor {
3911             domain: super::Domain::SELINUX,
3912             nspace: SELINUX_NAMESPACE,
3913             alias: Some("yek".to_string()),
3914             blob: None,
3915         };
3916 
3917         let selinux_granted_key = db
3918             .grant(&selinux_key, CALLER_UID, 12, PVEC1, |k, a| {
3919                 assert_eq!(*a, PVEC1);
3920                 assert_eq!(
3921                     *k,
3922                     KeyDescriptor {
3923                         domain: super::Domain::SELINUX,
3924                         // namespace must be the supplied SELinux
3925                         // namespace.
3926                         nspace: SELINUX_NAMESPACE,
3927                         alias: Some("yek".to_string()),
3928                         blob: None,
3929                     }
3930                 );
3931                 Ok(())
3932             })
3933             .unwrap();
3934 
3935         assert_eq!(
3936             selinux_granted_key,
3937             KeyDescriptor {
3938                 domain: super::Domain::GRANT,
3939                 // The grantid is next_random + 1 due to the mock random number generator.
3940                 nspace: next_random + 1,
3941                 alias: None,
3942                 blob: None,
3943             }
3944         );
3945 
3946         // This should update the existing grant with PVEC2.
3947         let selinux_granted_key = db
3948             .grant(&selinux_key, CALLER_UID, 12, PVEC2, |k, a| {
3949                 assert_eq!(*a, PVEC2);
3950                 assert_eq!(
3951                     *k,
3952                     KeyDescriptor {
3953                         domain: super::Domain::SELINUX,
3954                         // namespace must be the supplied SELinux
3955                         // namespace.
3956                         nspace: SELINUX_NAMESPACE,
3957                         alias: Some("yek".to_string()),
3958                         blob: None,
3959                     }
3960                 );
3961                 Ok(())
3962             })
3963             .unwrap();
3964 
3965         assert_eq!(
3966             selinux_granted_key,
3967             KeyDescriptor {
3968                 domain: super::Domain::GRANT,
3969                 // Same grant id as before. The entry was only updated.
3970                 nspace: next_random + 1,
3971                 alias: None,
3972                 blob: None,
3973             }
3974         );
3975 
3976         {
3977             // Limiting scope of stmt, because it borrows db.
3978             let mut stmt = db
3979                 .conn
3980                 .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
3981             let mut rows =
3982                 stmt.query_map::<(i64, u32, i64, KeyPermSet), _, _>(NO_PARAMS, |row| {
3983                     Ok((
3984                         row.get(0)?,
3985                         row.get(1)?,
3986                         row.get(2)?,
3987                         KeyPermSet::from(row.get::<_, i32>(3)?),
3988                     ))
3989                 })?;
3990 
3991             let r = rows.next().unwrap().unwrap();
3992             assert_eq!(r, (next_random, GRANTEE_UID, 1, PVEC1));
3993             let r = rows.next().unwrap().unwrap();
3994             assert_eq!(r, (next_random + 1, GRANTEE_UID, 2, PVEC2));
3995             assert!(rows.next().is_none());
3996         }
3997 
3998         debug_dump_keyentry_table(&mut db)?;
3999         println!("app_key {:?}", app_key);
4000         println!("selinux_key {:?}", selinux_key);
4001 
4002         db.ungrant(&app_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
4003         db.ungrant(&selinux_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
4004 
4005         Ok(())
4006     }
4007 
4008     static TEST_KEY_BLOB: &[u8] = b"my test blob";
4009     static TEST_CERT_BLOB: &[u8] = b"my test cert";
4010     static TEST_CERT_CHAIN_BLOB: &[u8] = b"my test cert_chain";
4011 
4012     #[test]
test_set_blob() -> Result<()>4013     fn test_set_blob() -> Result<()> {
4014         let key_id = KEY_ID_LOCK.get(3000);
4015         let mut db = new_test_db()?;
4016         let mut blob_metadata = BlobMetaData::new();
4017         blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
4018         db.set_blob(
4019             &key_id,
4020             SubComponentType::KEY_BLOB,
4021             Some(TEST_KEY_BLOB),
4022             Some(&blob_metadata),
4023         )?;
4024         db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
4025         db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
4026         drop(key_id);
4027 
4028         let mut stmt = db.conn.prepare(
4029             "SELECT subcomponent_type, keyentryid, blob, id FROM persistent.blobentry
4030                 ORDER BY subcomponent_type ASC;",
4031         )?;
4032         let mut rows = stmt
4033             .query_map::<((SubComponentType, i64, Vec<u8>), i64), _, _>(NO_PARAMS, |row| {
4034                 Ok(((row.get(0)?, row.get(1)?, row.get(2)?), row.get(3)?))
4035             })?;
4036         let (r, id) = rows.next().unwrap().unwrap();
4037         assert_eq!(r, (SubComponentType::KEY_BLOB, 3000, TEST_KEY_BLOB.to_vec()));
4038         let (r, _) = rows.next().unwrap().unwrap();
4039         assert_eq!(r, (SubComponentType::CERT, 3000, TEST_CERT_BLOB.to_vec()));
4040         let (r, _) = rows.next().unwrap().unwrap();
4041         assert_eq!(r, (SubComponentType::CERT_CHAIN, 3000, TEST_CERT_CHAIN_BLOB.to_vec()));
4042 
4043         drop(rows);
4044         drop(stmt);
4045 
4046         assert_eq!(
4047             db.with_transaction(TransactionBehavior::Immediate, |tx| {
4048                 BlobMetaData::load_from_db(id, tx).no_gc()
4049             })
4050             .expect("Should find blob metadata."),
4051             blob_metadata
4052         );
4053         Ok(())
4054     }
4055 
4056     static TEST_ALIAS: &str = "my super duper key";
4057 
4058     #[test]
test_insert_and_load_full_keyentry_domain_app() -> Result<()>4059     fn test_insert_and_load_full_keyentry_domain_app() -> Result<()> {
4060         let mut db = new_test_db()?;
4061         let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
4062             .context("test_insert_and_load_full_keyentry_domain_app")?
4063             .0;
4064         let (_key_guard, key_entry) = db
4065             .load_key_entry(
4066                 &KeyDescriptor {
4067                     domain: Domain::APP,
4068                     nspace: 0,
4069                     alias: Some(TEST_ALIAS.to_string()),
4070                     blob: None,
4071                 },
4072                 KeyType::Client,
4073                 KeyEntryLoadBits::BOTH,
4074                 1,
4075                 |_k, _av| Ok(()),
4076             )
4077             .unwrap();
4078         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4079 
4080         db.unbind_key(
4081             &KeyDescriptor {
4082                 domain: Domain::APP,
4083                 nspace: 0,
4084                 alias: Some(TEST_ALIAS.to_string()),
4085                 blob: None,
4086             },
4087             KeyType::Client,
4088             1,
4089             |_, _| Ok(()),
4090         )
4091         .unwrap();
4092 
4093         assert_eq!(
4094             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4095             db.load_key_entry(
4096                 &KeyDescriptor {
4097                     domain: Domain::APP,
4098                     nspace: 0,
4099                     alias: Some(TEST_ALIAS.to_string()),
4100                     blob: None,
4101                 },
4102                 KeyType::Client,
4103                 KeyEntryLoadBits::NONE,
4104                 1,
4105                 |_k, _av| Ok(()),
4106             )
4107             .unwrap_err()
4108             .root_cause()
4109             .downcast_ref::<KsError>()
4110         );
4111 
4112         Ok(())
4113     }
4114 
4115     #[test]
test_insert_and_load_certificate_entry_domain_app() -> Result<()>4116     fn test_insert_and_load_certificate_entry_domain_app() -> Result<()> {
4117         let mut db = new_test_db()?;
4118 
4119         db.store_new_certificate(
4120             &KeyDescriptor {
4121                 domain: Domain::APP,
4122                 nspace: 1,
4123                 alias: Some(TEST_ALIAS.to_string()),
4124                 blob: None,
4125             },
4126             KeyType::Client,
4127             TEST_CERT_BLOB,
4128             &KEYSTORE_UUID,
4129         )
4130         .expect("Trying to insert cert.");
4131 
4132         let (_key_guard, mut key_entry) = db
4133             .load_key_entry(
4134                 &KeyDescriptor {
4135                     domain: Domain::APP,
4136                     nspace: 1,
4137                     alias: Some(TEST_ALIAS.to_string()),
4138                     blob: None,
4139                 },
4140                 KeyType::Client,
4141                 KeyEntryLoadBits::PUBLIC,
4142                 1,
4143                 |_k, _av| Ok(()),
4144             )
4145             .expect("Trying to read certificate entry.");
4146 
4147         assert!(key_entry.pure_cert());
4148         assert!(key_entry.cert().is_none());
4149         assert_eq!(key_entry.take_cert_chain(), Some(TEST_CERT_BLOB.to_vec()));
4150 
4151         db.unbind_key(
4152             &KeyDescriptor {
4153                 domain: Domain::APP,
4154                 nspace: 1,
4155                 alias: Some(TEST_ALIAS.to_string()),
4156                 blob: None,
4157             },
4158             KeyType::Client,
4159             1,
4160             |_, _| Ok(()),
4161         )
4162         .unwrap();
4163 
4164         assert_eq!(
4165             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4166             db.load_key_entry(
4167                 &KeyDescriptor {
4168                     domain: Domain::APP,
4169                     nspace: 1,
4170                     alias: Some(TEST_ALIAS.to_string()),
4171                     blob: None,
4172                 },
4173                 KeyType::Client,
4174                 KeyEntryLoadBits::NONE,
4175                 1,
4176                 |_k, _av| Ok(()),
4177             )
4178             .unwrap_err()
4179             .root_cause()
4180             .downcast_ref::<KsError>()
4181         );
4182 
4183         Ok(())
4184     }
4185 
4186     #[test]
test_insert_and_load_full_keyentry_domain_selinux() -> Result<()>4187     fn test_insert_and_load_full_keyentry_domain_selinux() -> Result<()> {
4188         let mut db = new_test_db()?;
4189         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
4190             .context("test_insert_and_load_full_keyentry_domain_selinux")?
4191             .0;
4192         let (_key_guard, key_entry) = db
4193             .load_key_entry(
4194                 &KeyDescriptor {
4195                     domain: Domain::SELINUX,
4196                     nspace: 1,
4197                     alias: Some(TEST_ALIAS.to_string()),
4198                     blob: None,
4199                 },
4200                 KeyType::Client,
4201                 KeyEntryLoadBits::BOTH,
4202                 1,
4203                 |_k, _av| Ok(()),
4204             )
4205             .unwrap();
4206         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4207 
4208         db.unbind_key(
4209             &KeyDescriptor {
4210                 domain: Domain::SELINUX,
4211                 nspace: 1,
4212                 alias: Some(TEST_ALIAS.to_string()),
4213                 blob: None,
4214             },
4215             KeyType::Client,
4216             1,
4217             |_, _| Ok(()),
4218         )
4219         .unwrap();
4220 
4221         assert_eq!(
4222             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4223             db.load_key_entry(
4224                 &KeyDescriptor {
4225                     domain: Domain::SELINUX,
4226                     nspace: 1,
4227                     alias: Some(TEST_ALIAS.to_string()),
4228                     blob: None,
4229                 },
4230                 KeyType::Client,
4231                 KeyEntryLoadBits::NONE,
4232                 1,
4233                 |_k, _av| Ok(()),
4234             )
4235             .unwrap_err()
4236             .root_cause()
4237             .downcast_ref::<KsError>()
4238         );
4239 
4240         Ok(())
4241     }
4242 
4243     #[test]
test_insert_and_load_full_keyentry_domain_key_id() -> Result<()>4244     fn test_insert_and_load_full_keyentry_domain_key_id() -> Result<()> {
4245         let mut db = new_test_db()?;
4246         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
4247             .context("test_insert_and_load_full_keyentry_domain_key_id")?
4248             .0;
4249         let (_, key_entry) = db
4250             .load_key_entry(
4251                 &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
4252                 KeyType::Client,
4253                 KeyEntryLoadBits::BOTH,
4254                 1,
4255                 |_k, _av| Ok(()),
4256             )
4257             .unwrap();
4258 
4259         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4260 
4261         db.unbind_key(
4262             &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
4263             KeyType::Client,
4264             1,
4265             |_, _| Ok(()),
4266         )
4267         .unwrap();
4268 
4269         assert_eq!(
4270             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4271             db.load_key_entry(
4272                 &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
4273                 KeyType::Client,
4274                 KeyEntryLoadBits::NONE,
4275                 1,
4276                 |_k, _av| Ok(()),
4277             )
4278             .unwrap_err()
4279             .root_cause()
4280             .downcast_ref::<KsError>()
4281         );
4282 
4283         Ok(())
4284     }
4285 
4286     #[test]
test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()>4287     fn test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()> {
4288         let mut db = new_test_db()?;
4289         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(123))
4290             .context("test_check_and_update_key_usage_count_with_limited_use_key")?
4291             .0;
4292         // Update the usage count of the limited use key.
4293         db.check_and_update_key_usage_count(key_id)?;
4294 
4295         let (_key_guard, key_entry) = db.load_key_entry(
4296             &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
4297             KeyType::Client,
4298             KeyEntryLoadBits::BOTH,
4299             1,
4300             |_k, _av| Ok(()),
4301         )?;
4302 
4303         // The usage count is decremented now.
4304         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, Some(122)));
4305 
4306         Ok(())
4307     }
4308 
4309     #[test]
test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()>4310     fn test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()> {
4311         let mut db = new_test_db()?;
4312         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(1))
4313             .context("test_check_and_update_key_usage_count_with_exhausted_limited_use_key")?
4314             .0;
4315         // Update the usage count of the limited use key.
4316         db.check_and_update_key_usage_count(key_id).expect(concat!(
4317             "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
4318             "This should succeed."
4319         ));
4320 
4321         // Try to update the exhausted limited use key.
4322         let e = db.check_and_update_key_usage_count(key_id).expect_err(concat!(
4323             "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
4324             "This should fail."
4325         ));
4326         assert_eq!(
4327             &KsError::Km(ErrorCode::INVALID_KEY_BLOB),
4328             e.root_cause().downcast_ref::<KsError>().unwrap()
4329         );
4330 
4331         Ok(())
4332     }
4333 
4334     #[test]
test_insert_and_load_full_keyentry_from_grant() -> Result<()>4335     fn test_insert_and_load_full_keyentry_from_grant() -> Result<()> {
4336         let mut db = new_test_db()?;
4337         let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
4338             .context("test_insert_and_load_full_keyentry_from_grant")?
4339             .0;
4340 
4341         let granted_key = db
4342             .grant(
4343                 &KeyDescriptor {
4344                     domain: Domain::APP,
4345                     nspace: 0,
4346                     alias: Some(TEST_ALIAS.to_string()),
4347                     blob: None,
4348                 },
4349                 1,
4350                 2,
4351                 key_perm_set![KeyPerm::Use],
4352                 |_k, _av| Ok(()),
4353             )
4354             .unwrap();
4355 
4356         debug_dump_grant_table(&mut db)?;
4357 
4358         let (_key_guard, key_entry) = db
4359             .load_key_entry(&granted_key, KeyType::Client, KeyEntryLoadBits::BOTH, 2, |k, av| {
4360                 assert_eq!(Domain::GRANT, k.domain);
4361                 assert!(av.unwrap().includes(KeyPerm::Use));
4362                 Ok(())
4363             })
4364             .unwrap();
4365 
4366         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4367 
4368         db.unbind_key(&granted_key, KeyType::Client, 2, |_, _| Ok(())).unwrap();
4369 
4370         assert_eq!(
4371             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4372             db.load_key_entry(
4373                 &granted_key,
4374                 KeyType::Client,
4375                 KeyEntryLoadBits::NONE,
4376                 2,
4377                 |_k, _av| Ok(()),
4378             )
4379             .unwrap_err()
4380             .root_cause()
4381             .downcast_ref::<KsError>()
4382         );
4383 
4384         Ok(())
4385     }
4386 
4387     // This test attempts to load a key by key id while the caller is not the owner
4388     // but a grant exists for the given key and the caller.
4389     #[test]
test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()>4390     fn test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()> {
4391         let mut db = new_test_db()?;
4392         const OWNER_UID: u32 = 1u32;
4393         const GRANTEE_UID: u32 = 2u32;
4394         const SOMEONE_ELSE_UID: u32 = 3u32;
4395         let key_id = make_test_key_entry(&mut db, Domain::APP, OWNER_UID as i64, TEST_ALIAS, None)
4396             .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?
4397             .0;
4398 
4399         db.grant(
4400             &KeyDescriptor {
4401                 domain: Domain::APP,
4402                 nspace: 0,
4403                 alias: Some(TEST_ALIAS.to_string()),
4404                 blob: None,
4405             },
4406             OWNER_UID,
4407             GRANTEE_UID,
4408             key_perm_set![KeyPerm::Use],
4409             |_k, _av| Ok(()),
4410         )
4411         .unwrap();
4412 
4413         debug_dump_grant_table(&mut db)?;
4414 
4415         let id_descriptor =
4416             KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, ..Default::default() };
4417 
4418         let (_, key_entry) = db
4419             .load_key_entry(
4420                 &id_descriptor,
4421                 KeyType::Client,
4422                 KeyEntryLoadBits::BOTH,
4423                 GRANTEE_UID,
4424                 |k, av| {
4425                     assert_eq!(Domain::APP, k.domain);
4426                     assert_eq!(OWNER_UID as i64, k.nspace);
4427                     assert!(av.unwrap().includes(KeyPerm::Use));
4428                     Ok(())
4429                 },
4430             )
4431             .unwrap();
4432 
4433         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4434 
4435         let (_, key_entry) = db
4436             .load_key_entry(
4437                 &id_descriptor,
4438                 KeyType::Client,
4439                 KeyEntryLoadBits::BOTH,
4440                 SOMEONE_ELSE_UID,
4441                 |k, av| {
4442                     assert_eq!(Domain::APP, k.domain);
4443                     assert_eq!(OWNER_UID as i64, k.nspace);
4444                     assert!(av.is_none());
4445                     Ok(())
4446                 },
4447             )
4448             .unwrap();
4449 
4450         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4451 
4452         db.unbind_key(&id_descriptor, KeyType::Client, OWNER_UID, |_, _| Ok(())).unwrap();
4453 
4454         assert_eq!(
4455             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4456             db.load_key_entry(
4457                 &id_descriptor,
4458                 KeyType::Client,
4459                 KeyEntryLoadBits::NONE,
4460                 GRANTEE_UID,
4461                 |_k, _av| Ok(()),
4462             )
4463             .unwrap_err()
4464             .root_cause()
4465             .downcast_ref::<KsError>()
4466         );
4467 
4468         Ok(())
4469     }
4470 
4471     // Creates a key migrates it to a different location and then tries to access it by the old
4472     // and new location.
4473     #[test]
test_migrate_key_app_to_app() -> Result<()>4474     fn test_migrate_key_app_to_app() -> Result<()> {
4475         let mut db = new_test_db()?;
4476         const SOURCE_UID: u32 = 1u32;
4477         const DESTINATION_UID: u32 = 2u32;
4478         static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
4479         static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
4480         let key_id_guard =
4481             make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
4482                 .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
4483 
4484         let source_descriptor: KeyDescriptor = KeyDescriptor {
4485             domain: Domain::APP,
4486             nspace: -1,
4487             alias: Some(SOURCE_ALIAS.to_string()),
4488             blob: None,
4489         };
4490 
4491         let destination_descriptor: KeyDescriptor = KeyDescriptor {
4492             domain: Domain::APP,
4493             nspace: -1,
4494             alias: Some(DESTINATION_ALIAS.to_string()),
4495             blob: None,
4496         };
4497 
4498         let key_id = key_id_guard.id();
4499 
4500         db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
4501             Ok(())
4502         })
4503         .unwrap();
4504 
4505         let (_, key_entry) = db
4506             .load_key_entry(
4507                 &destination_descriptor,
4508                 KeyType::Client,
4509                 KeyEntryLoadBits::BOTH,
4510                 DESTINATION_UID,
4511                 |k, av| {
4512                     assert_eq!(Domain::APP, k.domain);
4513                     assert_eq!(DESTINATION_UID as i64, k.nspace);
4514                     assert!(av.is_none());
4515                     Ok(())
4516                 },
4517             )
4518             .unwrap();
4519 
4520         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4521 
4522         assert_eq!(
4523             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4524             db.load_key_entry(
4525                 &source_descriptor,
4526                 KeyType::Client,
4527                 KeyEntryLoadBits::NONE,
4528                 SOURCE_UID,
4529                 |_k, _av| Ok(()),
4530             )
4531             .unwrap_err()
4532             .root_cause()
4533             .downcast_ref::<KsError>()
4534         );
4535 
4536         Ok(())
4537     }
4538 
4539     // Creates a key migrates it to a different location and then tries to access it by the old
4540     // and new location.
4541     #[test]
test_migrate_key_app_to_selinux() -> Result<()>4542     fn test_migrate_key_app_to_selinux() -> Result<()> {
4543         let mut db = new_test_db()?;
4544         const SOURCE_UID: u32 = 1u32;
4545         const DESTINATION_UID: u32 = 2u32;
4546         const DESTINATION_NAMESPACE: i64 = 1000i64;
4547         static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
4548         static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
4549         let key_id_guard =
4550             make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
4551                 .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
4552 
4553         let source_descriptor: KeyDescriptor = KeyDescriptor {
4554             domain: Domain::APP,
4555             nspace: -1,
4556             alias: Some(SOURCE_ALIAS.to_string()),
4557             blob: None,
4558         };
4559 
4560         let destination_descriptor: KeyDescriptor = KeyDescriptor {
4561             domain: Domain::SELINUX,
4562             nspace: DESTINATION_NAMESPACE,
4563             alias: Some(DESTINATION_ALIAS.to_string()),
4564             blob: None,
4565         };
4566 
4567         let key_id = key_id_guard.id();
4568 
4569         db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
4570             Ok(())
4571         })
4572         .unwrap();
4573 
4574         let (_, key_entry) = db
4575             .load_key_entry(
4576                 &destination_descriptor,
4577                 KeyType::Client,
4578                 KeyEntryLoadBits::BOTH,
4579                 DESTINATION_UID,
4580                 |k, av| {
4581                     assert_eq!(Domain::SELINUX, k.domain);
4582                     assert_eq!(DESTINATION_NAMESPACE as i64, k.nspace);
4583                     assert!(av.is_none());
4584                     Ok(())
4585                 },
4586             )
4587             .unwrap();
4588 
4589         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4590 
4591         assert_eq!(
4592             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4593             db.load_key_entry(
4594                 &source_descriptor,
4595                 KeyType::Client,
4596                 KeyEntryLoadBits::NONE,
4597                 SOURCE_UID,
4598                 |_k, _av| Ok(()),
4599             )
4600             .unwrap_err()
4601             .root_cause()
4602             .downcast_ref::<KsError>()
4603         );
4604 
4605         Ok(())
4606     }
4607 
4608     // Creates two keys and tries to migrate the first to the location of the second which
4609     // is expected to fail.
4610     #[test]
test_migrate_key_destination_occupied() -> Result<()>4611     fn test_migrate_key_destination_occupied() -> Result<()> {
4612         let mut db = new_test_db()?;
4613         const SOURCE_UID: u32 = 1u32;
4614         const DESTINATION_UID: u32 = 2u32;
4615         static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
4616         static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
4617         let key_id_guard =
4618             make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
4619                 .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
4620         make_test_key_entry(&mut db, Domain::APP, DESTINATION_UID as i64, DESTINATION_ALIAS, None)
4621             .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
4622 
4623         let destination_descriptor: KeyDescriptor = KeyDescriptor {
4624             domain: Domain::APP,
4625             nspace: -1,
4626             alias: Some(DESTINATION_ALIAS.to_string()),
4627             blob: None,
4628         };
4629 
4630         assert_eq!(
4631             Some(&KsError::Rc(ResponseCode::INVALID_ARGUMENT)),
4632             db.migrate_key_namespace(
4633                 key_id_guard,
4634                 &destination_descriptor,
4635                 DESTINATION_UID,
4636                 |_k| Ok(())
4637             )
4638             .unwrap_err()
4639             .root_cause()
4640             .downcast_ref::<KsError>()
4641         );
4642 
4643         Ok(())
4644     }
4645 
4646     #[test]
test_upgrade_0_to_1()4647     fn test_upgrade_0_to_1() {
4648         const ALIAS1: &str = "test_upgrade_0_to_1_1";
4649         const ALIAS2: &str = "test_upgrade_0_to_1_2";
4650         const ALIAS3: &str = "test_upgrade_0_to_1_3";
4651         const UID: u32 = 33;
4652         let temp_dir = Arc::new(TempDir::new("test_upgrade_0_to_1").unwrap());
4653         let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
4654         let key_id_untouched1 =
4655             make_test_key_entry(&mut db, Domain::APP, UID as i64, ALIAS1, None).unwrap().id();
4656         let key_id_untouched2 =
4657             make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS2, false).unwrap().id();
4658         let key_id_deleted =
4659             make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS3, true).unwrap().id();
4660 
4661         let (_, key_entry) = db
4662             .load_key_entry(
4663                 &KeyDescriptor {
4664                     domain: Domain::APP,
4665                     nspace: -1,
4666                     alias: Some(ALIAS1.to_string()),
4667                     blob: None,
4668                 },
4669                 KeyType::Client,
4670                 KeyEntryLoadBits::BOTH,
4671                 UID,
4672                 |k, av| {
4673                     assert_eq!(Domain::APP, k.domain);
4674                     assert_eq!(UID as i64, k.nspace);
4675                     assert!(av.is_none());
4676                     Ok(())
4677                 },
4678             )
4679             .unwrap();
4680         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
4681         let (_, key_entry) = db
4682             .load_key_entry(
4683                 &KeyDescriptor {
4684                     domain: Domain::APP,
4685                     nspace: -1,
4686                     alias: Some(ALIAS2.to_string()),
4687                     blob: None,
4688                 },
4689                 KeyType::Client,
4690                 KeyEntryLoadBits::BOTH,
4691                 UID,
4692                 |k, av| {
4693                     assert_eq!(Domain::APP, k.domain);
4694                     assert_eq!(UID as i64, k.nspace);
4695                     assert!(av.is_none());
4696                     Ok(())
4697                 },
4698             )
4699             .unwrap();
4700         assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
4701         let (_, key_entry) = db
4702             .load_key_entry(
4703                 &KeyDescriptor {
4704                     domain: Domain::APP,
4705                     nspace: -1,
4706                     alias: Some(ALIAS3.to_string()),
4707                     blob: None,
4708                 },
4709                 KeyType::Client,
4710                 KeyEntryLoadBits::BOTH,
4711                 UID,
4712                 |k, av| {
4713                     assert_eq!(Domain::APP, k.domain);
4714                     assert_eq!(UID as i64, k.nspace);
4715                     assert!(av.is_none());
4716                     Ok(())
4717                 },
4718             )
4719             .unwrap();
4720         assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_deleted, true));
4721 
4722         db.with_transaction(TransactionBehavior::Immediate, |tx| {
4723             KeystoreDB::from_0_to_1(tx).no_gc()
4724         })
4725         .unwrap();
4726 
4727         let (_, key_entry) = db
4728             .load_key_entry(
4729                 &KeyDescriptor {
4730                     domain: Domain::APP,
4731                     nspace: -1,
4732                     alias: Some(ALIAS1.to_string()),
4733                     blob: None,
4734                 },
4735                 KeyType::Client,
4736                 KeyEntryLoadBits::BOTH,
4737                 UID,
4738                 |k, av| {
4739                     assert_eq!(Domain::APP, k.domain);
4740                     assert_eq!(UID as i64, k.nspace);
4741                     assert!(av.is_none());
4742                     Ok(())
4743                 },
4744             )
4745             .unwrap();
4746         assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
4747         let (_, key_entry) = db
4748             .load_key_entry(
4749                 &KeyDescriptor {
4750                     domain: Domain::APP,
4751                     nspace: -1,
4752                     alias: Some(ALIAS2.to_string()),
4753                     blob: None,
4754                 },
4755                 KeyType::Client,
4756                 KeyEntryLoadBits::BOTH,
4757                 UID,
4758                 |k, av| {
4759                     assert_eq!(Domain::APP, k.domain);
4760                     assert_eq!(UID as i64, k.nspace);
4761                     assert!(av.is_none());
4762                     Ok(())
4763                 },
4764             )
4765             .unwrap();
4766         assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
4767         assert_eq!(
4768             Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
4769             db.load_key_entry(
4770                 &KeyDescriptor {
4771                     domain: Domain::APP,
4772                     nspace: -1,
4773                     alias: Some(ALIAS3.to_string()),
4774                     blob: None,
4775                 },
4776                 KeyType::Client,
4777                 KeyEntryLoadBits::BOTH,
4778                 UID,
4779                 |k, av| {
4780                     assert_eq!(Domain::APP, k.domain);
4781                     assert_eq!(UID as i64, k.nspace);
4782                     assert!(av.is_none());
4783                     Ok(())
4784                 },
4785             )
4786             .unwrap_err()
4787             .root_cause()
4788             .downcast_ref::<KsError>()
4789         );
4790     }
4791 
4792     static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
4793 
4794     #[test]
test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()>4795     fn test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()> {
4796         let handle = {
4797             let temp_dir = Arc::new(TempDir::new("id_lock_test")?);
4798             let temp_dir_clone = temp_dir.clone();
4799             let mut db = KeystoreDB::new(temp_dir.path(), None)?;
4800             let key_id = make_test_key_entry(&mut db, Domain::APP, 33, KEY_LOCK_TEST_ALIAS, None)
4801                 .context("test_insert_and_load_full_keyentry_domain_app")?
4802                 .0;
4803             let (_key_guard, key_entry) = db
4804                 .load_key_entry(
4805                     &KeyDescriptor {
4806                         domain: Domain::APP,
4807                         nspace: 0,
4808                         alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
4809                         blob: None,
4810                     },
4811                     KeyType::Client,
4812                     KeyEntryLoadBits::BOTH,
4813                     33,
4814                     |_k, _av| Ok(()),
4815                 )
4816                 .unwrap();
4817             assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
4818             let state = Arc::new(AtomicU8::new(1));
4819             let state2 = state.clone();
4820 
4821             // Spawning a second thread that attempts to acquire the key id lock
4822             // for the same key as the primary thread. The primary thread then
4823             // waits, thereby forcing the secondary thread into the second stage
4824             // of acquiring the lock (see KEY ID LOCK 2/2 above).
4825             // The test succeeds if the secondary thread observes the transition
4826             // of `state` from 1 to 2, despite having a whole second to overtake
4827             // the primary thread.
4828             let handle = thread::spawn(move || {
4829                 let temp_dir = temp_dir_clone;
4830                 let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
4831                 assert!(db
4832                     .load_key_entry(
4833                         &KeyDescriptor {
4834                             domain: Domain::APP,
4835                             nspace: 0,
4836                             alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
4837                             blob: None,
4838                         },
4839                         KeyType::Client,
4840                         KeyEntryLoadBits::BOTH,
4841                         33,
4842                         |_k, _av| Ok(()),
4843                     )
4844                     .is_ok());
4845                 // We should only see a 2 here because we can only return
4846                 // from load_key_entry when the `_key_guard` expires,
4847                 // which happens at the end of the scope.
4848                 assert_eq!(2, state2.load(Ordering::Relaxed));
4849             });
4850 
4851             thread::sleep(std::time::Duration::from_millis(1000));
4852 
4853             assert_eq!(Ok(1), state.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed));
4854 
4855             // Return the handle from this scope so we can join with the
4856             // secondary thread after the key id lock has expired.
4857             handle
4858             // This is where the `_key_guard` goes out of scope,
4859             // which is the reason for concurrent load_key_entry on the same key
4860             // to unblock.
4861         };
4862         // Join with the secondary thread and unwrap, to propagate failing asserts to the
4863         // main test thread. We will not see failing asserts in secondary threads otherwise.
4864         handle.join().unwrap();
4865         Ok(())
4866     }
4867 
4868     #[test]
test_database_busy_error_code()4869     fn test_database_busy_error_code() {
4870         let temp_dir =
4871             TempDir::new("test_database_busy_error_code_").expect("Failed to create temp dir.");
4872 
4873         let mut db1 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database1.");
4874         let mut db2 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database2.");
4875 
4876         let _tx1 = db1
4877             .conn
4878             .transaction_with_behavior(TransactionBehavior::Immediate)
4879             .expect("Failed to create first transaction.");
4880 
4881         let error = db2
4882             .conn
4883             .transaction_with_behavior(TransactionBehavior::Immediate)
4884             .context("Transaction begin failed.")
4885             .expect_err("This should fail.");
4886         let root_cause = error.root_cause();
4887         if let Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) =
4888             root_cause.downcast_ref::<rusqlite::ffi::Error>()
4889         {
4890             return;
4891         }
4892         panic!(
4893             "Unexpected error {:?} \n{:?} \n{:?}",
4894             error,
4895             root_cause,
4896             root_cause.downcast_ref::<rusqlite::ffi::Error>()
4897         )
4898     }
4899 
4900     #[cfg(disabled)]
4901     #[test]
test_large_number_of_concurrent_db_manipulations() -> Result<()>4902     fn test_large_number_of_concurrent_db_manipulations() -> Result<()> {
4903         let temp_dir = Arc::new(
4904             TempDir::new("test_large_number_of_concurrent_db_manipulations_")
4905                 .expect("Failed to create temp dir."),
4906         );
4907 
4908         let test_begin = Instant::now();
4909 
4910         const KEY_COUNT: u32 = 500u32;
4911         let mut db =
4912             new_test_db_with_gc(temp_dir.path(), |_, _| Ok(())).expect("Failed to open database.");
4913         const OPEN_DB_COUNT: u32 = 50u32;
4914 
4915         let mut actual_key_count = KEY_COUNT;
4916         // First insert KEY_COUNT keys.
4917         for count in 0..KEY_COUNT {
4918             if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
4919                 actual_key_count = count;
4920                 break;
4921             }
4922             let alias = format!("test_alias_{}", count);
4923             make_test_key_entry(&mut db, Domain::APP, 1, &alias, None)
4924                 .expect("Failed to make key entry.");
4925         }
4926 
4927         // Insert more keys from a different thread and into a different namespace.
4928         let temp_dir1 = temp_dir.clone();
4929         let handle1 = thread::spawn(move || {
4930             let mut db = new_test_db_with_gc(temp_dir1.path(), |_, _| Ok(()))
4931                 .expect("Failed to open database.");
4932 
4933             for count in 0..actual_key_count {
4934                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
4935                     return;
4936                 }
4937                 let alias = format!("test_alias_{}", count);
4938                 make_test_key_entry(&mut db, Domain::APP, 2, &alias, None)
4939                     .expect("Failed to make key entry.");
4940             }
4941 
4942             // then unbind them again.
4943             for count in 0..actual_key_count {
4944                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
4945                     return;
4946                 }
4947                 let key = KeyDescriptor {
4948                     domain: Domain::APP,
4949                     nspace: -1,
4950                     alias: Some(format!("test_alias_{}", count)),
4951                     blob: None,
4952                 };
4953                 db.unbind_key(&key, KeyType::Client, 2, |_, _| Ok(())).expect("Unbind Failed.");
4954             }
4955         });
4956 
4957         // And start unbinding the first set of keys.
4958         let temp_dir2 = temp_dir.clone();
4959         let handle2 = thread::spawn(move || {
4960             let mut db = new_test_db_with_gc(temp_dir2.path(), |_, _| Ok(()))
4961                 .expect("Failed to open database.");
4962 
4963             for count in 0..actual_key_count {
4964                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
4965                     return;
4966                 }
4967                 let key = KeyDescriptor {
4968                     domain: Domain::APP,
4969                     nspace: -1,
4970                     alias: Some(format!("test_alias_{}", count)),
4971                     blob: None,
4972                 };
4973                 db.unbind_key(&key, KeyType::Client, 1, |_, _| Ok(())).expect("Unbind Failed.");
4974             }
4975         });
4976 
4977         // While a lot of inserting and deleting is going on we have to open database connections
4978         // successfully and use them.
4979         // This clone is not redundant, because temp_dir needs to be kept alive until db goes
4980         // out of scope.
4981         #[allow(clippy::redundant_clone)]
4982         let temp_dir4 = temp_dir.clone();
4983         let handle4 = thread::spawn(move || {
4984             for count in 0..OPEN_DB_COUNT {
4985                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
4986                     return;
4987                 }
4988                 let mut db = new_test_db_with_gc(temp_dir4.path(), |_, _| Ok(()))
4989                     .expect("Failed to open database.");
4990 
4991                 let alias = format!("test_alias_{}", count);
4992                 make_test_key_entry(&mut db, Domain::APP, 3, &alias, None)
4993                     .expect("Failed to make key entry.");
4994                 let key = KeyDescriptor {
4995                     domain: Domain::APP,
4996                     nspace: -1,
4997                     alias: Some(alias),
4998                     blob: None,
4999                 };
5000                 db.unbind_key(&key, KeyType::Client, 3, |_, _| Ok(())).expect("Unbind Failed.");
5001             }
5002         });
5003 
5004         handle1.join().expect("Thread 1 panicked.");
5005         handle2.join().expect("Thread 2 panicked.");
5006         handle4.join().expect("Thread 4 panicked.");
5007 
5008         Ok(())
5009     }
5010 
5011     #[test]
list() -> Result<()>5012     fn list() -> Result<()> {
5013         let temp_dir = TempDir::new("list_test")?;
5014         let mut db = KeystoreDB::new(temp_dir.path(), None)?;
5015         static LIST_O_ENTRIES: &[(Domain, i64, &str)] = &[
5016             (Domain::APP, 1, "test1"),
5017             (Domain::APP, 1, "test2"),
5018             (Domain::APP, 1, "test3"),
5019             (Domain::APP, 1, "test4"),
5020             (Domain::APP, 1, "test5"),
5021             (Domain::APP, 1, "test6"),
5022             (Domain::APP, 1, "test7"),
5023             (Domain::APP, 2, "test1"),
5024             (Domain::APP, 2, "test2"),
5025             (Domain::APP, 2, "test3"),
5026             (Domain::APP, 2, "test4"),
5027             (Domain::APP, 2, "test5"),
5028             (Domain::APP, 2, "test6"),
5029             (Domain::APP, 2, "test8"),
5030             (Domain::SELINUX, 100, "test1"),
5031             (Domain::SELINUX, 100, "test2"),
5032             (Domain::SELINUX, 100, "test3"),
5033             (Domain::SELINUX, 100, "test4"),
5034             (Domain::SELINUX, 100, "test5"),
5035             (Domain::SELINUX, 100, "test6"),
5036             (Domain::SELINUX, 100, "test9"),
5037         ];
5038 
5039         let list_o_keys: Vec<(i64, i64)> = LIST_O_ENTRIES
5040             .iter()
5041             .map(|(domain, ns, alias)| {
5042                 let entry = make_test_key_entry(&mut db, *domain, *ns, *alias, None)
5043                     .unwrap_or_else(|e| {
5044                         panic!("Failed to insert {:?} {} {}. Error {:?}", domain, ns, alias, e)
5045                     });
5046                 (entry.id(), *ns)
5047             })
5048             .collect();
5049 
5050         for (domain, namespace) in
5051             &[(Domain::APP, 1i64), (Domain::APP, 2i64), (Domain::SELINUX, 100i64)]
5052         {
5053             let mut list_o_descriptors: Vec<KeyDescriptor> = LIST_O_ENTRIES
5054                 .iter()
5055                 .filter_map(|(domain, ns, alias)| match ns {
5056                     ns if *ns == *namespace => Some(KeyDescriptor {
5057                         domain: *domain,
5058                         nspace: *ns,
5059                         alias: Some(alias.to_string()),
5060                         blob: None,
5061                     }),
5062                     _ => None,
5063                 })
5064                 .collect();
5065             list_o_descriptors.sort();
5066             let mut list_result = db.list(*domain, *namespace, KeyType::Client)?;
5067             list_result.sort();
5068             assert_eq!(list_o_descriptors, list_result);
5069 
5070             let mut list_o_ids: Vec<i64> = list_o_descriptors
5071                 .into_iter()
5072                 .map(|d| {
5073                     let (_, entry) = db
5074                         .load_key_entry(
5075                             &d,
5076                             KeyType::Client,
5077                             KeyEntryLoadBits::NONE,
5078                             *namespace as u32,
5079                             |_, _| Ok(()),
5080                         )
5081                         .unwrap();
5082                     entry.id()
5083                 })
5084                 .collect();
5085             list_o_ids.sort_unstable();
5086             let mut loaded_entries: Vec<i64> = list_o_keys
5087                 .iter()
5088                 .filter_map(|(id, ns)| match ns {
5089                     ns if *ns == *namespace => Some(*id),
5090                     _ => None,
5091                 })
5092                 .collect();
5093             loaded_entries.sort_unstable();
5094             assert_eq!(list_o_ids, loaded_entries);
5095         }
5096         assert_eq!(Vec::<KeyDescriptor>::new(), db.list(Domain::SELINUX, 101, KeyType::Client)?);
5097 
5098         Ok(())
5099     }
5100 
5101     // Helpers
5102 
5103     // Checks that the given result is an error containing the given string.
check_result_is_error_containing_string<T>(result: Result<T>, target: &str)5104     fn check_result_is_error_containing_string<T>(result: Result<T>, target: &str) {
5105         let error_str = format!(
5106             "{:#?}",
5107             result.err().unwrap_or_else(|| panic!("Expected the error: {}", target))
5108         );
5109         assert!(
5110             error_str.contains(target),
5111             "The string \"{}\" should contain \"{}\"",
5112             error_str,
5113             target
5114         );
5115     }
5116 
5117     #[derive(Debug, PartialEq)]
5118     struct KeyEntryRow {
5119         id: i64,
5120         key_type: KeyType,
5121         domain: Option<Domain>,
5122         namespace: Option<i64>,
5123         alias: Option<String>,
5124         state: KeyLifeCycle,
5125         km_uuid: Option<Uuid>,
5126     }
5127 
get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>>5128     fn get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>> {
5129         db.conn
5130             .prepare("SELECT * FROM persistent.keyentry;")?
5131             .query_map(NO_PARAMS, |row| {
5132                 Ok(KeyEntryRow {
5133                     id: row.get(0)?,
5134                     key_type: row.get(1)?,
5135                     domain: row.get::<_, Option<_>>(2)?.map(Domain),
5136                     namespace: row.get(3)?,
5137                     alias: row.get(4)?,
5138                     state: row.get(5)?,
5139                     km_uuid: row.get(6)?,
5140                 })
5141             })?
5142             .map(|r| r.context("Could not read keyentry row."))
5143             .collect::<Result<Vec<_>>>()
5144     }
5145 
5146     struct RemoteProvValues {
5147         cert_chain: Vec<u8>,
5148         priv_key: Vec<u8>,
5149         batch_cert: Vec<u8>,
5150     }
5151 
load_attestation_key_pool( db: &mut KeystoreDB, expiration_date: i64, namespace: i64, base_byte: u8, ) -> Result<RemoteProvValues>5152     fn load_attestation_key_pool(
5153         db: &mut KeystoreDB,
5154         expiration_date: i64,
5155         namespace: i64,
5156         base_byte: u8,
5157     ) -> Result<RemoteProvValues> {
5158         let public_key: Vec<u8> = vec![base_byte, 0x02 * base_byte];
5159         let cert_chain: Vec<u8> = vec![0x03 * base_byte, 0x04 * base_byte];
5160         let priv_key: Vec<u8> = vec![0x05 * base_byte, 0x06 * base_byte];
5161         let raw_public_key: Vec<u8> = vec![0x0b * base_byte, 0x0c * base_byte];
5162         let batch_cert: Vec<u8> = vec![base_byte * 0x0d, base_byte * 0x0e];
5163         db.create_attestation_key_entry(&public_key, &raw_public_key, &priv_key, &KEYSTORE_UUID)?;
5164         db.store_signed_attestation_certificate_chain(
5165             &raw_public_key,
5166             &batch_cert,
5167             &cert_chain,
5168             expiration_date,
5169             &KEYSTORE_UUID,
5170         )?;
5171         db.assign_attestation_key(Domain::APP, namespace, &KEYSTORE_UUID)?;
5172         Ok(RemoteProvValues { cert_chain, priv_key, batch_cert })
5173     }
5174 
5175     // Note: The parameters and SecurityLevel associations are nonsensical. This
5176     // collection is only used to check if the parameters are preserved as expected by the
5177     // database.
make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter>5178     fn make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter> {
5179         let mut params = vec![
5180             KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::TRUSTED_ENVIRONMENT),
5181             KeyParameter::new(
5182                 KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
5183                 SecurityLevel::TRUSTED_ENVIRONMENT,
5184             ),
5185             KeyParameter::new(
5186                 KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
5187                 SecurityLevel::TRUSTED_ENVIRONMENT,
5188             ),
5189             KeyParameter::new(
5190                 KeyParameterValue::Algorithm(Algorithm::RSA),
5191                 SecurityLevel::TRUSTED_ENVIRONMENT,
5192             ),
5193             KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::TRUSTED_ENVIRONMENT),
5194             KeyParameter::new(
5195                 KeyParameterValue::BlockMode(BlockMode::ECB),
5196                 SecurityLevel::TRUSTED_ENVIRONMENT,
5197             ),
5198             KeyParameter::new(
5199                 KeyParameterValue::BlockMode(BlockMode::GCM),
5200                 SecurityLevel::TRUSTED_ENVIRONMENT,
5201             ),
5202             KeyParameter::new(KeyParameterValue::Digest(Digest::NONE), SecurityLevel::STRONGBOX),
5203             KeyParameter::new(
5204                 KeyParameterValue::Digest(Digest::MD5),
5205                 SecurityLevel::TRUSTED_ENVIRONMENT,
5206             ),
5207             KeyParameter::new(
5208                 KeyParameterValue::Digest(Digest::SHA_2_224),
5209                 SecurityLevel::TRUSTED_ENVIRONMENT,
5210             ),
5211             KeyParameter::new(
5212                 KeyParameterValue::Digest(Digest::SHA_2_256),
5213                 SecurityLevel::STRONGBOX,
5214             ),
5215             KeyParameter::new(
5216                 KeyParameterValue::PaddingMode(PaddingMode::NONE),
5217                 SecurityLevel::TRUSTED_ENVIRONMENT,
5218             ),
5219             KeyParameter::new(
5220                 KeyParameterValue::PaddingMode(PaddingMode::RSA_OAEP),
5221                 SecurityLevel::TRUSTED_ENVIRONMENT,
5222             ),
5223             KeyParameter::new(
5224                 KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
5225                 SecurityLevel::STRONGBOX,
5226             ),
5227             KeyParameter::new(
5228                 KeyParameterValue::PaddingMode(PaddingMode::RSA_PKCS1_1_5_SIGN),
5229                 SecurityLevel::TRUSTED_ENVIRONMENT,
5230             ),
5231             KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::TRUSTED_ENVIRONMENT),
5232             KeyParameter::new(KeyParameterValue::MinMacLength(256), SecurityLevel::STRONGBOX),
5233             KeyParameter::new(
5234                 KeyParameterValue::EcCurve(EcCurve::P_224),
5235                 SecurityLevel::TRUSTED_ENVIRONMENT,
5236             ),
5237             KeyParameter::new(KeyParameterValue::EcCurve(EcCurve::P_256), SecurityLevel::STRONGBOX),
5238             KeyParameter::new(
5239                 KeyParameterValue::EcCurve(EcCurve::P_384),
5240                 SecurityLevel::TRUSTED_ENVIRONMENT,
5241             ),
5242             KeyParameter::new(
5243                 KeyParameterValue::EcCurve(EcCurve::P_521),
5244                 SecurityLevel::TRUSTED_ENVIRONMENT,
5245             ),
5246             KeyParameter::new(
5247                 KeyParameterValue::RSAPublicExponent(3),
5248                 SecurityLevel::TRUSTED_ENVIRONMENT,
5249             ),
5250             KeyParameter::new(
5251                 KeyParameterValue::IncludeUniqueID,
5252                 SecurityLevel::TRUSTED_ENVIRONMENT,
5253             ),
5254             KeyParameter::new(KeyParameterValue::BootLoaderOnly, SecurityLevel::STRONGBOX),
5255             KeyParameter::new(KeyParameterValue::RollbackResistance, SecurityLevel::STRONGBOX),
5256             KeyParameter::new(
5257                 KeyParameterValue::ActiveDateTime(1234567890),
5258                 SecurityLevel::STRONGBOX,
5259             ),
5260             KeyParameter::new(
5261                 KeyParameterValue::OriginationExpireDateTime(1234567890),
5262                 SecurityLevel::TRUSTED_ENVIRONMENT,
5263             ),
5264             KeyParameter::new(
5265                 KeyParameterValue::UsageExpireDateTime(1234567890),
5266                 SecurityLevel::TRUSTED_ENVIRONMENT,
5267             ),
5268             KeyParameter::new(
5269                 KeyParameterValue::MinSecondsBetweenOps(1234567890),
5270                 SecurityLevel::TRUSTED_ENVIRONMENT,
5271             ),
5272             KeyParameter::new(
5273                 KeyParameterValue::MaxUsesPerBoot(1234567890),
5274                 SecurityLevel::TRUSTED_ENVIRONMENT,
5275             ),
5276             KeyParameter::new(KeyParameterValue::UserID(1), SecurityLevel::STRONGBOX),
5277             KeyParameter::new(KeyParameterValue::UserSecureID(42), SecurityLevel::STRONGBOX),
5278             KeyParameter::new(
5279                 KeyParameterValue::NoAuthRequired,
5280                 SecurityLevel::TRUSTED_ENVIRONMENT,
5281             ),
5282             KeyParameter::new(
5283                 KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType::PASSWORD),
5284                 SecurityLevel::TRUSTED_ENVIRONMENT,
5285             ),
5286             KeyParameter::new(KeyParameterValue::AuthTimeout(1234567890), SecurityLevel::SOFTWARE),
5287             KeyParameter::new(KeyParameterValue::AllowWhileOnBody, SecurityLevel::SOFTWARE),
5288             KeyParameter::new(
5289                 KeyParameterValue::TrustedUserPresenceRequired,
5290                 SecurityLevel::TRUSTED_ENVIRONMENT,
5291             ),
5292             KeyParameter::new(
5293                 KeyParameterValue::TrustedConfirmationRequired,
5294                 SecurityLevel::TRUSTED_ENVIRONMENT,
5295             ),
5296             KeyParameter::new(
5297                 KeyParameterValue::UnlockedDeviceRequired,
5298                 SecurityLevel::TRUSTED_ENVIRONMENT,
5299             ),
5300             KeyParameter::new(
5301                 KeyParameterValue::ApplicationID(vec![1u8, 2u8, 3u8, 4u8]),
5302                 SecurityLevel::SOFTWARE,
5303             ),
5304             KeyParameter::new(
5305                 KeyParameterValue::ApplicationData(vec![4u8, 3u8, 2u8, 1u8]),
5306                 SecurityLevel::SOFTWARE,
5307             ),
5308             KeyParameter::new(
5309                 KeyParameterValue::CreationDateTime(12345677890),
5310                 SecurityLevel::SOFTWARE,
5311             ),
5312             KeyParameter::new(
5313                 KeyParameterValue::KeyOrigin(KeyOrigin::GENERATED),
5314                 SecurityLevel::TRUSTED_ENVIRONMENT,
5315             ),
5316             KeyParameter::new(
5317                 KeyParameterValue::RootOfTrust(vec![3u8, 2u8, 1u8, 4u8]),
5318                 SecurityLevel::TRUSTED_ENVIRONMENT,
5319             ),
5320             KeyParameter::new(KeyParameterValue::OSVersion(1), SecurityLevel::TRUSTED_ENVIRONMENT),
5321             KeyParameter::new(KeyParameterValue::OSPatchLevel(2), SecurityLevel::SOFTWARE),
5322             KeyParameter::new(
5323                 KeyParameterValue::UniqueID(vec![4u8, 3u8, 1u8, 2u8]),
5324                 SecurityLevel::SOFTWARE,
5325             ),
5326             KeyParameter::new(
5327                 KeyParameterValue::AttestationChallenge(vec![4u8, 3u8, 1u8, 2u8]),
5328                 SecurityLevel::TRUSTED_ENVIRONMENT,
5329             ),
5330             KeyParameter::new(
5331                 KeyParameterValue::AttestationApplicationID(vec![4u8, 3u8, 1u8, 2u8]),
5332                 SecurityLevel::TRUSTED_ENVIRONMENT,
5333             ),
5334             KeyParameter::new(
5335                 KeyParameterValue::AttestationIdBrand(vec![4u8, 3u8, 1u8, 2u8]),
5336                 SecurityLevel::TRUSTED_ENVIRONMENT,
5337             ),
5338             KeyParameter::new(
5339                 KeyParameterValue::AttestationIdDevice(vec![4u8, 3u8, 1u8, 2u8]),
5340                 SecurityLevel::TRUSTED_ENVIRONMENT,
5341             ),
5342             KeyParameter::new(
5343                 KeyParameterValue::AttestationIdProduct(vec![4u8, 3u8, 1u8, 2u8]),
5344                 SecurityLevel::TRUSTED_ENVIRONMENT,
5345             ),
5346             KeyParameter::new(
5347                 KeyParameterValue::AttestationIdSerial(vec![4u8, 3u8, 1u8, 2u8]),
5348                 SecurityLevel::TRUSTED_ENVIRONMENT,
5349             ),
5350             KeyParameter::new(
5351                 KeyParameterValue::AttestationIdIMEI(vec![4u8, 3u8, 1u8, 2u8]),
5352                 SecurityLevel::TRUSTED_ENVIRONMENT,
5353             ),
5354             KeyParameter::new(
5355                 KeyParameterValue::AttestationIdMEID(vec![4u8, 3u8, 1u8, 2u8]),
5356                 SecurityLevel::TRUSTED_ENVIRONMENT,
5357             ),
5358             KeyParameter::new(
5359                 KeyParameterValue::AttestationIdManufacturer(vec![4u8, 3u8, 1u8, 2u8]),
5360                 SecurityLevel::TRUSTED_ENVIRONMENT,
5361             ),
5362             KeyParameter::new(
5363                 KeyParameterValue::AttestationIdModel(vec![4u8, 3u8, 1u8, 2u8]),
5364                 SecurityLevel::TRUSTED_ENVIRONMENT,
5365             ),
5366             KeyParameter::new(
5367                 KeyParameterValue::VendorPatchLevel(3),
5368                 SecurityLevel::TRUSTED_ENVIRONMENT,
5369             ),
5370             KeyParameter::new(
5371                 KeyParameterValue::BootPatchLevel(4),
5372                 SecurityLevel::TRUSTED_ENVIRONMENT,
5373             ),
5374             KeyParameter::new(
5375                 KeyParameterValue::AssociatedData(vec![4u8, 3u8, 1u8, 2u8]),
5376                 SecurityLevel::TRUSTED_ENVIRONMENT,
5377             ),
5378             KeyParameter::new(
5379                 KeyParameterValue::Nonce(vec![4u8, 3u8, 1u8, 2u8]),
5380                 SecurityLevel::TRUSTED_ENVIRONMENT,
5381             ),
5382             KeyParameter::new(
5383                 KeyParameterValue::MacLength(256),
5384                 SecurityLevel::TRUSTED_ENVIRONMENT,
5385             ),
5386             KeyParameter::new(
5387                 KeyParameterValue::ResetSinceIdRotation,
5388                 SecurityLevel::TRUSTED_ENVIRONMENT,
5389             ),
5390             KeyParameter::new(
5391                 KeyParameterValue::ConfirmationToken(vec![5u8, 5u8, 5u8, 5u8]),
5392                 SecurityLevel::TRUSTED_ENVIRONMENT,
5393             ),
5394         ];
5395         if let Some(value) = max_usage_count {
5396             params.push(KeyParameter::new(
5397                 KeyParameterValue::UsageCountLimit(value),
5398                 SecurityLevel::SOFTWARE,
5399             ));
5400         }
5401         params
5402     }
5403 
make_test_key_entry( db: &mut KeystoreDB, domain: Domain, namespace: i64, alias: &str, max_usage_count: Option<i32>, ) -> Result<KeyIdGuard>5404     fn make_test_key_entry(
5405         db: &mut KeystoreDB,
5406         domain: Domain,
5407         namespace: i64,
5408         alias: &str,
5409         max_usage_count: Option<i32>,
5410     ) -> Result<KeyIdGuard> {
5411         let key_id = db.create_key_entry(&domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
5412         let mut blob_metadata = BlobMetaData::new();
5413         blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
5414         blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
5415         blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
5416         blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
5417         blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
5418 
5419         db.set_blob(
5420             &key_id,
5421             SubComponentType::KEY_BLOB,
5422             Some(TEST_KEY_BLOB),
5423             Some(&blob_metadata),
5424         )?;
5425         db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
5426         db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
5427 
5428         let params = make_test_params(max_usage_count);
5429         db.insert_keyparameter(&key_id, &params)?;
5430 
5431         let mut metadata = KeyMetaData::new();
5432         metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
5433         db.insert_key_metadata(&key_id, &metadata)?;
5434         rebind_alias(db, &key_id, alias, domain, namespace)?;
5435         Ok(key_id)
5436     }
5437 
make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry5438     fn make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry {
5439         let params = make_test_params(max_usage_count);
5440 
5441         let mut blob_metadata = BlobMetaData::new();
5442         blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
5443         blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
5444         blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
5445         blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
5446         blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
5447 
5448         let mut metadata = KeyMetaData::new();
5449         metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
5450 
5451         KeyEntry {
5452             id: key_id,
5453             key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
5454             cert: Some(TEST_CERT_BLOB.to_vec()),
5455             cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
5456             km_uuid: KEYSTORE_UUID,
5457             parameters: params,
5458             metadata,
5459             pure_cert: false,
5460         }
5461     }
5462 
make_bootlevel_key_entry( db: &mut KeystoreDB, domain: Domain, namespace: i64, alias: &str, logical_only: bool, ) -> Result<KeyIdGuard>5463     fn make_bootlevel_key_entry(
5464         db: &mut KeystoreDB,
5465         domain: Domain,
5466         namespace: i64,
5467         alias: &str,
5468         logical_only: bool,
5469     ) -> Result<KeyIdGuard> {
5470         let key_id = db.create_key_entry(&domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
5471         let mut blob_metadata = BlobMetaData::new();
5472         if !logical_only {
5473             blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
5474         }
5475         blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
5476 
5477         db.set_blob(
5478             &key_id,
5479             SubComponentType::KEY_BLOB,
5480             Some(TEST_KEY_BLOB),
5481             Some(&blob_metadata),
5482         )?;
5483         db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
5484         db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
5485 
5486         let mut params = make_test_params(None);
5487         params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
5488 
5489         db.insert_keyparameter(&key_id, &params)?;
5490 
5491         let mut metadata = KeyMetaData::new();
5492         metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
5493         db.insert_key_metadata(&key_id, &metadata)?;
5494         rebind_alias(db, &key_id, alias, domain, namespace)?;
5495         Ok(key_id)
5496     }
5497 
make_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry5498     fn make_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry {
5499         let mut params = make_test_params(None);
5500         params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
5501 
5502         let mut blob_metadata = BlobMetaData::new();
5503         if !logical_only {
5504             blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
5505         }
5506         blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
5507 
5508         let mut metadata = KeyMetaData::new();
5509         metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
5510 
5511         KeyEntry {
5512             id: key_id,
5513             key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
5514             cert: Some(TEST_CERT_BLOB.to_vec()),
5515             cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
5516             km_uuid: KEYSTORE_UUID,
5517             parameters: params,
5518             metadata,
5519             pure_cert: false,
5520         }
5521     }
5522 
debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()>5523     fn debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()> {
5524         let mut stmt = db.conn.prepare(
5525             "SELECT id, key_type, domain, namespace, alias, state, km_uuid FROM persistent.keyentry;",
5526         )?;
5527         let rows = stmt.query_map::<(i64, KeyType, i32, i64, String, KeyLifeCycle, Uuid), _, _>(
5528             NO_PARAMS,
5529             |row| {
5530                 Ok((
5531                     row.get(0)?,
5532                     row.get(1)?,
5533                     row.get(2)?,
5534                     row.get(3)?,
5535                     row.get(4)?,
5536                     row.get(5)?,
5537                     row.get(6)?,
5538                 ))
5539             },
5540         )?;
5541 
5542         println!("Key entry table rows:");
5543         for r in rows {
5544             let (id, key_type, domain, namespace, alias, state, km_uuid) = r.unwrap();
5545             println!(
5546                 "    id: {} KeyType: {:?} Domain: {} Namespace: {} Alias: {} State: {:?} KmUuid: {:?}",
5547                 id, key_type, domain, namespace, alias, state, km_uuid
5548             );
5549         }
5550         Ok(())
5551     }
5552 
debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()>5553     fn debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()> {
5554         let mut stmt = db
5555             .conn
5556             .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
5557         let rows = stmt.query_map::<(i64, i64, i64, i64), _, _>(NO_PARAMS, |row| {
5558             Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
5559         })?;
5560 
5561         println!("Grant table rows:");
5562         for r in rows {
5563             let (id, gt, ki, av) = r.unwrap();
5564             println!("    id: {} grantee: {} key_id: {} access_vector: {}", id, gt, ki, av);
5565         }
5566         Ok(())
5567     }
5568 
5569     // Use a custom random number generator that repeats each number once.
5570     // This allows us to test repeated elements.
5571 
5572     thread_local! {
5573         static RANDOM_COUNTER: RefCell<i64> = RefCell::new(0);
5574     }
5575 
reset_random()5576     fn reset_random() {
5577         RANDOM_COUNTER.with(|counter| {
5578             *counter.borrow_mut() = 0;
5579         })
5580     }
5581 
random() -> i645582     pub fn random() -> i64 {
5583         RANDOM_COUNTER.with(|counter| {
5584             let result = *counter.borrow() / 2;
5585             *counter.borrow_mut() += 1;
5586             result
5587         })
5588     }
5589 
5590     #[test]
test_last_off_body() -> Result<()>5591     fn test_last_off_body() -> Result<()> {
5592         let mut db = new_test_db()?;
5593         db.insert_last_off_body(MonotonicRawTime::now());
5594         let tx = db.conn.transaction_with_behavior(TransactionBehavior::Immediate)?;
5595         tx.commit()?;
5596         let last_off_body_1 = db.get_last_off_body();
5597         let one_second = Duration::from_secs(1);
5598         thread::sleep(one_second);
5599         db.update_last_off_body(MonotonicRawTime::now());
5600         let tx2 = db.conn.transaction_with_behavior(TransactionBehavior::Immediate)?;
5601         tx2.commit()?;
5602         let last_off_body_2 = db.get_last_off_body();
5603         assert!(last_off_body_1 < last_off_body_2);
5604         Ok(())
5605     }
5606 
5607     #[test]
test_unbind_keys_for_user() -> Result<()>5608     fn test_unbind_keys_for_user() -> Result<()> {
5609         let mut db = new_test_db()?;
5610         db.unbind_keys_for_user(1, false)?;
5611 
5612         make_test_key_entry(&mut db, Domain::APP, 210000, TEST_ALIAS, None)?;
5613         make_test_key_entry(&mut db, Domain::APP, 110000, TEST_ALIAS, None)?;
5614         db.unbind_keys_for_user(2, false)?;
5615 
5616         assert_eq!(1, db.list(Domain::APP, 110000, KeyType::Client)?.len());
5617         assert_eq!(0, db.list(Domain::APP, 210000, KeyType::Client)?.len());
5618 
5619         db.unbind_keys_for_user(1, true)?;
5620         assert_eq!(0, db.list(Domain::APP, 110000, KeyType::Client)?.len());
5621 
5622         Ok(())
5623     }
5624 
5625     #[test]
test_unbind_keys_for_user_removes_superkeys() -> Result<()>5626     fn test_unbind_keys_for_user_removes_superkeys() -> Result<()> {
5627         let mut db = new_test_db()?;
5628         let super_key = keystore2_crypto::generate_aes256_key()?;
5629         let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
5630         let (encrypted_super_key, metadata) =
5631             SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
5632 
5633         let key_name_enc = SuperKeyType {
5634             alias: "test_super_key_1",
5635             algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
5636         };
5637 
5638         let key_name_nonenc = SuperKeyType {
5639             alias: "test_super_key_2",
5640             algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
5641         };
5642 
5643         // Install two super keys.
5644         db.store_super_key(
5645             1,
5646             &key_name_nonenc,
5647             &super_key,
5648             &BlobMetaData::new(),
5649             &KeyMetaData::new(),
5650         )?;
5651         db.store_super_key(1, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
5652 
5653         // Check that both can be found in the database.
5654         assert!(db.load_super_key(&key_name_enc, 1)?.is_some());
5655         assert!(db.load_super_key(&key_name_nonenc, 1)?.is_some());
5656 
5657         // Install the same keys for a different user.
5658         db.store_super_key(
5659             2,
5660             &key_name_nonenc,
5661             &super_key,
5662             &BlobMetaData::new(),
5663             &KeyMetaData::new(),
5664         )?;
5665         db.store_super_key(2, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
5666 
5667         // Check that the second pair of keys can be found in the database.
5668         assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
5669         assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
5670 
5671         // Delete only encrypted keys.
5672         db.unbind_keys_for_user(1, true)?;
5673 
5674         // The encrypted superkey should be gone now.
5675         assert!(db.load_super_key(&key_name_enc, 1)?.is_none());
5676         assert!(db.load_super_key(&key_name_nonenc, 1)?.is_some());
5677 
5678         // Reinsert the encrypted key.
5679         db.store_super_key(1, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
5680 
5681         // Check that both can be found in the database, again..
5682         assert!(db.load_super_key(&key_name_enc, 1)?.is_some());
5683         assert!(db.load_super_key(&key_name_nonenc, 1)?.is_some());
5684 
5685         // Delete all even unencrypted keys.
5686         db.unbind_keys_for_user(1, false)?;
5687 
5688         // Both should be gone now.
5689         assert!(db.load_super_key(&key_name_enc, 1)?.is_none());
5690         assert!(db.load_super_key(&key_name_nonenc, 1)?.is_none());
5691 
5692         // Check that the second pair of keys was untouched.
5693         assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
5694         assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
5695 
5696         Ok(())
5697     }
5698 
5699     #[test]
test_store_super_key() -> Result<()>5700     fn test_store_super_key() -> Result<()> {
5701         let mut db = new_test_db()?;
5702         let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
5703         let super_key = keystore2_crypto::generate_aes256_key()?;
5704         let secret_bytes = b"keystore2 is great.";
5705         let (encrypted_secret, iv, tag) =
5706             keystore2_crypto::aes_gcm_encrypt(secret_bytes, &super_key)?;
5707 
5708         let (encrypted_super_key, metadata) =
5709             SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
5710         db.store_super_key(
5711             1,
5712             &USER_SUPER_KEY,
5713             &encrypted_super_key,
5714             &metadata,
5715             &KeyMetaData::new(),
5716         )?;
5717 
5718         // Check if super key exists.
5719         assert!(db.key_exists(Domain::APP, 1, USER_SUPER_KEY.alias, KeyType::Super)?);
5720 
5721         let (_, key_entry) = db.load_super_key(&USER_SUPER_KEY, 1)?.unwrap();
5722         let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(
5723             USER_SUPER_KEY.algorithm,
5724             key_entry,
5725             &pw,
5726             None,
5727         )?;
5728 
5729         let decrypted_secret_bytes = loaded_super_key.decrypt(&encrypted_secret, &iv, &tag)?;
5730         assert_eq!(secret_bytes, &*decrypted_secret_bytes);
5731 
5732         Ok(())
5733     }
5734 
get_valid_statsd_storage_types() -> Vec<MetricsStorage>5735     fn get_valid_statsd_storage_types() -> Vec<MetricsStorage> {
5736         vec![
5737             MetricsStorage::KEY_ENTRY,
5738             MetricsStorage::KEY_ENTRY_ID_INDEX,
5739             MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
5740             MetricsStorage::BLOB_ENTRY,
5741             MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
5742             MetricsStorage::KEY_PARAMETER,
5743             MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX,
5744             MetricsStorage::KEY_METADATA,
5745             MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX,
5746             MetricsStorage::GRANT,
5747             MetricsStorage::AUTH_TOKEN,
5748             MetricsStorage::BLOB_METADATA,
5749             MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
5750         ]
5751     }
5752 
5753     /// Perform a simple check to ensure that we can query all the storage types
5754     /// that are supported by the DB. Check for reasonable values.
5755     #[test]
test_query_all_valid_table_sizes() -> Result<()>5756     fn test_query_all_valid_table_sizes() -> Result<()> {
5757         const PAGE_SIZE: i32 = 4096;
5758 
5759         let mut db = new_test_db()?;
5760 
5761         for t in get_valid_statsd_storage_types() {
5762             let stat = db.get_storage_stat(t)?;
5763             // AuthToken can be less than a page since it's in a btree, not sqlite
5764             // TODO(b/187474736) stop using if-let here
5765             if let MetricsStorage::AUTH_TOKEN = t {
5766             } else {
5767                 assert!(stat.size >= PAGE_SIZE);
5768             }
5769             assert!(stat.size >= stat.unused_size);
5770         }
5771 
5772         Ok(())
5773     }
5774 
get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats>5775     fn get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats> {
5776         get_valid_statsd_storage_types()
5777             .into_iter()
5778             .map(|t| (t.0, db.get_storage_stat(t).unwrap()))
5779             .collect()
5780     }
5781 
assert_storage_increased( db: &mut KeystoreDB, increased_storage_types: Vec<MetricsStorage>, baseline: &mut BTreeMap<i32, StorageStats>, )5782     fn assert_storage_increased(
5783         db: &mut KeystoreDB,
5784         increased_storage_types: Vec<MetricsStorage>,
5785         baseline: &mut BTreeMap<i32, StorageStats>,
5786     ) {
5787         for storage in increased_storage_types {
5788             // Verify the expected storage increased.
5789             let new = db.get_storage_stat(storage).unwrap();
5790             let storage = storage;
5791             let old = &baseline[&storage.0];
5792             assert!(new.size >= old.size, "{}: {} >= {}", storage.0, new.size, old.size);
5793             assert!(
5794                 new.unused_size <= old.unused_size,
5795                 "{}: {} <= {}",
5796                 storage.0,
5797                 new.unused_size,
5798                 old.unused_size
5799             );
5800 
5801             // Update the baseline with the new value so that it succeeds in the
5802             // later comparison.
5803             baseline.insert(storage.0, new);
5804         }
5805 
5806         // Get an updated map of the storage and verify there were no unexpected changes.
5807         let updated_stats = get_storage_stats_map(db);
5808         assert_eq!(updated_stats.len(), baseline.len());
5809 
5810         for &k in baseline.keys() {
5811             let stringify = |map: &BTreeMap<i32, StorageStats>| -> String {
5812                 let mut s = String::new();
5813                 for &k in map.keys() {
5814                     writeln!(&mut s, "  {}: {}, {}", &k, map[&k].size, map[&k].unused_size)
5815                         .expect("string concat failed");
5816                 }
5817                 s
5818             };
5819 
5820             assert!(
5821                 updated_stats[&k].size == baseline[&k].size
5822                     && updated_stats[&k].unused_size == baseline[&k].unused_size,
5823                 "updated_stats:\n{}\nbaseline:\n{}",
5824                 stringify(&updated_stats),
5825                 stringify(baseline)
5826             );
5827         }
5828     }
5829 
5830     #[test]
test_verify_key_table_size_reporting() -> Result<()>5831     fn test_verify_key_table_size_reporting() -> Result<()> {
5832         let mut db = new_test_db()?;
5833         let mut working_stats = get_storage_stats_map(&mut db);
5834 
5835         let key_id = db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
5836         assert_storage_increased(
5837             &mut db,
5838             vec![
5839                 MetricsStorage::KEY_ENTRY,
5840                 MetricsStorage::KEY_ENTRY_ID_INDEX,
5841                 MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
5842             ],
5843             &mut working_stats,
5844         );
5845 
5846         let mut blob_metadata = BlobMetaData::new();
5847         blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
5848         db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), None)?;
5849         assert_storage_increased(
5850             &mut db,
5851             vec![
5852                 MetricsStorage::BLOB_ENTRY,
5853                 MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
5854                 MetricsStorage::BLOB_METADATA,
5855                 MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
5856             ],
5857             &mut working_stats,
5858         );
5859 
5860         let params = make_test_params(None);
5861         db.insert_keyparameter(&key_id, &params)?;
5862         assert_storage_increased(
5863             &mut db,
5864             vec![MetricsStorage::KEY_PARAMETER, MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX],
5865             &mut working_stats,
5866         );
5867 
5868         let mut metadata = KeyMetaData::new();
5869         metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
5870         db.insert_key_metadata(&key_id, &metadata)?;
5871         assert_storage_increased(
5872             &mut db,
5873             vec![MetricsStorage::KEY_METADATA, MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX],
5874             &mut working_stats,
5875         );
5876 
5877         let mut sum = 0;
5878         for stat in working_stats.values() {
5879             sum += stat.size;
5880         }
5881         let total = db.get_storage_stat(MetricsStorage::DATABASE)?.size;
5882         assert!(sum <= total, "Expected sum <= total. sum: {}, total: {}", sum, total);
5883 
5884         Ok(())
5885     }
5886 
5887     #[test]
test_verify_auth_table_size_reporting() -> Result<()>5888     fn test_verify_auth_table_size_reporting() -> Result<()> {
5889         let mut db = new_test_db()?;
5890         let mut working_stats = get_storage_stats_map(&mut db);
5891         db.insert_auth_token(&HardwareAuthToken {
5892             challenge: 123,
5893             userId: 456,
5894             authenticatorId: 789,
5895             authenticatorType: kmhw_authenticator_type::ANY,
5896             timestamp: Timestamp { milliSeconds: 10 },
5897             mac: b"mac".to_vec(),
5898         });
5899         assert_storage_increased(&mut db, vec![MetricsStorage::AUTH_TOKEN], &mut working_stats);
5900         Ok(())
5901     }
5902 
5903     #[test]
test_verify_grant_table_size_reporting() -> Result<()>5904     fn test_verify_grant_table_size_reporting() -> Result<()> {
5905         const OWNER: i64 = 1;
5906         let mut db = new_test_db()?;
5907         make_test_key_entry(&mut db, Domain::APP, OWNER, TEST_ALIAS, None)?;
5908 
5909         let mut working_stats = get_storage_stats_map(&mut db);
5910         db.grant(
5911             &KeyDescriptor {
5912                 domain: Domain::APP,
5913                 nspace: 0,
5914                 alias: Some(TEST_ALIAS.to_string()),
5915                 blob: None,
5916             },
5917             OWNER as u32,
5918             123,
5919             key_perm_set![KeyPerm::Use],
5920             |_, _| Ok(()),
5921         )?;
5922 
5923         assert_storage_increased(&mut db, vec![MetricsStorage::GRANT], &mut working_stats);
5924 
5925         Ok(())
5926     }
5927 
5928     #[test]
find_auth_token_entry_returns_latest() -> Result<()>5929     fn find_auth_token_entry_returns_latest() -> Result<()> {
5930         let mut db = new_test_db()?;
5931         db.insert_auth_token(&HardwareAuthToken {
5932             challenge: 123,
5933             userId: 456,
5934             authenticatorId: 789,
5935             authenticatorType: kmhw_authenticator_type::ANY,
5936             timestamp: Timestamp { milliSeconds: 10 },
5937             mac: b"mac0".to_vec(),
5938         });
5939         std::thread::sleep(std::time::Duration::from_millis(1));
5940         db.insert_auth_token(&HardwareAuthToken {
5941             challenge: 123,
5942             userId: 457,
5943             authenticatorId: 789,
5944             authenticatorType: kmhw_authenticator_type::ANY,
5945             timestamp: Timestamp { milliSeconds: 12 },
5946             mac: b"mac1".to_vec(),
5947         });
5948         std::thread::sleep(std::time::Duration::from_millis(1));
5949         db.insert_auth_token(&HardwareAuthToken {
5950             challenge: 123,
5951             userId: 458,
5952             authenticatorId: 789,
5953             authenticatorType: kmhw_authenticator_type::ANY,
5954             timestamp: Timestamp { milliSeconds: 3 },
5955             mac: b"mac2".to_vec(),
5956         });
5957         // All three entries are in the database
5958         assert_eq!(db.perboot.auth_tokens_len(), 3);
5959         // It selected the most recent timestamp
5960         assert_eq!(db.find_auth_token_entry(|_| true).unwrap().0.auth_token.mac, b"mac2".to_vec());
5961         Ok(())
5962     }
5963 
5964     #[test]
test_load_key_descriptor() -> Result<()>5965     fn test_load_key_descriptor() -> Result<()> {
5966         let mut db = new_test_db()?;
5967         let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)?.0;
5968 
5969         let key = db.load_key_descriptor(key_id)?.unwrap();
5970 
5971         assert_eq!(key.domain, Domain::APP);
5972         assert_eq!(key.nspace, 1);
5973         assert_eq!(key.alias, Some(TEST_ALIAS.to_string()));
5974 
5975         // No such id
5976         assert_eq!(db.load_key_descriptor(key_id + 1)?, None);
5977         Ok(())
5978     }
5979 }
5980