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