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 #[cfg(test)] 49 pub mod tests; 50 51 use crate::gc::Gc; 52 use crate::impl_metadata; // This is in database/utils.rs 53 use crate::key_parameter::{KeyParameter, KeyParameterValue, Tag}; 54 use crate::ks_err; 55 use crate::permission::KeyPermSet; 56 use crate::utils::{get_current_time_in_milliseconds, watchdog as wd, AID_USER_OFFSET}; 57 use crate::{ 58 error::{Error as KsError, ErrorCode, ResponseCode}, 59 super_key::SuperKeyType, 60 }; 61 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ 62 HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType, 63 SecurityLevel::SecurityLevel, 64 }; 65 use android_security_metrics::aidl::android::security::metrics::{ 66 Storage::Storage as MetricsStorage, StorageStats::StorageStats, 67 }; 68 use android_system_keystore2::aidl::android::system::keystore2::{ 69 Domain::Domain, KeyDescriptor::KeyDescriptor, 70 }; 71 use anyhow::{anyhow, Context, Result}; 72 use keystore2_flags; 73 use std::{convert::TryFrom, convert::TryInto, ops::Deref, sync::LazyLock, time::SystemTimeError}; 74 use utils as db_utils; 75 use utils::SqlField; 76 77 use keystore2_crypto::ZVec; 78 use log::error; 79 #[cfg(not(test))] 80 use rand::prelude::random; 81 use rusqlite::{ 82 params, params_from_iter, 83 types::FromSql, 84 types::FromSqlResult, 85 types::ToSqlOutput, 86 types::{FromSqlError, Value, ValueRef}, 87 Connection, OptionalExtension, ToSql, Transaction, 88 }; 89 90 use std::{ 91 collections::{HashMap, HashSet}, 92 path::Path, 93 sync::{Arc, Condvar, Mutex}, 94 time::{Duration, SystemTime}, 95 }; 96 97 use TransactionBehavior::Immediate; 98 99 #[cfg(test)] 100 use tests::random; 101 102 /// Wrapper for `rusqlite::TransactionBehavior` which includes information about the transaction 103 /// being performed. 104 #[derive(Clone, Copy)] 105 enum TransactionBehavior { 106 Deferred, 107 Immediate(&'static str), 108 } 109 110 impl From<TransactionBehavior> for rusqlite::TransactionBehavior { from(val: TransactionBehavior) -> Self111 fn from(val: TransactionBehavior) -> Self { 112 match val { 113 TransactionBehavior::Deferred => rusqlite::TransactionBehavior::Deferred, 114 TransactionBehavior::Immediate(_) => rusqlite::TransactionBehavior::Immediate, 115 } 116 } 117 } 118 119 impl TransactionBehavior { name(&self) -> Option<&'static str>120 fn name(&self) -> Option<&'static str> { 121 match self { 122 TransactionBehavior::Deferred => None, 123 TransactionBehavior::Immediate(v) => Some(v), 124 } 125 } 126 } 127 128 /// Access information for a key. 129 #[derive(Debug)] 130 struct KeyAccessInfo { 131 key_id: i64, 132 descriptor: KeyDescriptor, 133 vector: Option<KeyPermSet>, 134 } 135 136 /// If the database returns a busy error code, retry after this interval. 137 const DB_BUSY_RETRY_INTERVAL: Duration = Duration::from_micros(500); 138 139 impl_metadata!( 140 /// A set of metadata for key entries. 141 #[derive(Debug, Default, Eq, PartialEq)] 142 pub struct KeyMetaData; 143 /// A metadata entry for key entries. 144 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] 145 pub enum KeyMetaEntry { 146 /// Date of the creation of the key entry. 147 CreationDate(DateTime) with accessor creation_date, 148 /// Expiration date for attestation keys. 149 AttestationExpirationDate(DateTime) with accessor attestation_expiration_date, 150 /// CBOR Blob that represents a COSE_Key and associated metadata needed for remote 151 /// provisioning 152 AttestationMacedPublicKey(Vec<u8>) with accessor attestation_maced_public_key, 153 /// Vector representing the raw public key so results from the server can be matched 154 /// to the right entry 155 AttestationRawPubKey(Vec<u8>) with accessor attestation_raw_pub_key, 156 /// SEC1 public key for ECDH encryption 157 Sec1PublicKey(Vec<u8>) with accessor sec1_public_key, 158 // --- ADD NEW META DATA FIELDS HERE --- 159 // For backwards compatibility add new entries only to 160 // end of this list and above this comment. 161 }; 162 ); 163 164 impl KeyMetaData { load_from_db(key_id: i64, tx: &Transaction) -> Result<Self>165 fn load_from_db(key_id: i64, tx: &Transaction) -> Result<Self> { 166 let mut stmt = tx 167 .prepare( 168 "SELECT tag, data from persistent.keymetadata 169 WHERE keyentryid = ?;", 170 ) 171 .context(ks_err!("KeyMetaData::load_from_db: prepare statement failed."))?; 172 173 let mut metadata: HashMap<i64, KeyMetaEntry> = Default::default(); 174 175 let mut rows = stmt 176 .query(params![key_id]) 177 .context(ks_err!("KeyMetaData::load_from_db: query failed."))?; 178 db_utils::with_rows_extract_all(&mut rows, |row| { 179 let db_tag: i64 = row.get(0).context("Failed to read tag.")?; 180 metadata.insert( 181 db_tag, 182 KeyMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row)) 183 .context("Failed to read KeyMetaEntry.")?, 184 ); 185 Ok(()) 186 }) 187 .context(ks_err!("KeyMetaData::load_from_db."))?; 188 189 Ok(Self { data: metadata }) 190 } 191 store_in_db(&self, key_id: i64, tx: &Transaction) -> Result<()>192 fn store_in_db(&self, key_id: i64, tx: &Transaction) -> Result<()> { 193 let mut stmt = tx 194 .prepare( 195 "INSERT or REPLACE INTO persistent.keymetadata (keyentryid, tag, data) 196 VALUES (?, ?, ?);", 197 ) 198 .context(ks_err!("KeyMetaData::store_in_db: Failed to prepare statement."))?; 199 200 let iter = self.data.iter(); 201 for (tag, entry) in iter { 202 stmt.insert(params![key_id, tag, entry,]).with_context(|| { 203 ks_err!("KeyMetaData::store_in_db: Failed to insert {:?}", entry) 204 })?; 205 } 206 Ok(()) 207 } 208 } 209 210 impl_metadata!( 211 /// A set of metadata for key blobs. 212 #[derive(Debug, Default, Eq, PartialEq)] 213 pub struct BlobMetaData; 214 /// A metadata entry for key blobs. 215 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] 216 pub enum BlobMetaEntry { 217 /// If present, indicates that the blob is encrypted with another key or a key derived 218 /// from a password. 219 EncryptedBy(EncryptedBy) with accessor encrypted_by, 220 /// If the blob is password encrypted this field is set to the 221 /// salt used for the key derivation. 222 Salt(Vec<u8>) with accessor salt, 223 /// If the blob is encrypted, this field is set to the initialization vector. 224 Iv(Vec<u8>) with accessor iv, 225 /// If the blob is encrypted, this field holds the AEAD TAG. 226 AeadTag(Vec<u8>) with accessor aead_tag, 227 /// The uuid of the owning KeyMint instance. 228 KmUuid(Uuid) with accessor km_uuid, 229 /// If the key is ECDH encrypted, this is the ephemeral public key 230 PublicKey(Vec<u8>) with accessor public_key, 231 /// If the key is encrypted with a MaxBootLevel key, this is the boot level 232 /// of that key 233 MaxBootLevel(i32) with accessor max_boot_level, 234 // --- ADD NEW META DATA FIELDS HERE --- 235 // For backwards compatibility add new entries only to 236 // end of this list and above this comment. 237 }; 238 ); 239 240 impl BlobMetaData { load_from_db(blob_id: i64, tx: &Transaction) -> Result<Self>241 fn load_from_db(blob_id: i64, tx: &Transaction) -> Result<Self> { 242 let mut stmt = tx 243 .prepare( 244 "SELECT tag, data from persistent.blobmetadata 245 WHERE blobentryid = ?;", 246 ) 247 .context(ks_err!("BlobMetaData::load_from_db: prepare statement failed."))?; 248 249 let mut metadata: HashMap<i64, BlobMetaEntry> = Default::default(); 250 251 let mut rows = stmt.query(params![blob_id]).context(ks_err!("query failed."))?; 252 db_utils::with_rows_extract_all(&mut rows, |row| { 253 let db_tag: i64 = row.get(0).context("Failed to read tag.")?; 254 metadata.insert( 255 db_tag, 256 BlobMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row)) 257 .context("Failed to read BlobMetaEntry.")?, 258 ); 259 Ok(()) 260 }) 261 .context(ks_err!("BlobMetaData::load_from_db"))?; 262 263 Ok(Self { data: metadata }) 264 } 265 store_in_db(&self, blob_id: i64, tx: &Transaction) -> Result<()>266 fn store_in_db(&self, blob_id: i64, tx: &Transaction) -> Result<()> { 267 let mut stmt = tx 268 .prepare( 269 "INSERT or REPLACE INTO persistent.blobmetadata (blobentryid, tag, data) 270 VALUES (?, ?, ?);", 271 ) 272 .context(ks_err!("BlobMetaData::store_in_db: Failed to prepare statement.",))?; 273 274 let iter = self.data.iter(); 275 for (tag, entry) in iter { 276 stmt.insert(params![blob_id, tag, entry,]).with_context(|| { 277 ks_err!("BlobMetaData::store_in_db: Failed to insert {:?}", entry) 278 })?; 279 } 280 Ok(()) 281 } 282 } 283 284 /// Indicates the type of the keyentry. 285 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] 286 pub enum KeyType { 287 /// This is a client key type. These keys are created or imported through the Keystore 2.0 288 /// AIDL interface android.system.keystore2. 289 Client, 290 /// This is a super key type. These keys are created by keystore itself and used to encrypt 291 /// other key blobs to provide LSKF binding. 292 Super, 293 } 294 295 impl ToSql for KeyType { to_sql(&self) -> rusqlite::Result<ToSqlOutput>296 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 297 Ok(ToSqlOutput::Owned(Value::Integer(match self { 298 KeyType::Client => 0, 299 KeyType::Super => 1, 300 }))) 301 } 302 } 303 304 impl FromSql for KeyType { column_result(value: ValueRef) -> FromSqlResult<Self>305 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 306 match i64::column_result(value)? { 307 0 => Ok(KeyType::Client), 308 1 => Ok(KeyType::Super), 309 v => Err(FromSqlError::OutOfRange(v)), 310 } 311 } 312 } 313 314 /// Uuid representation that can be stored in the database. 315 /// Right now it can only be initialized from SecurityLevel. 316 /// Once KeyMint provides a UUID type a corresponding From impl shall be added. 317 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] 318 pub struct Uuid([u8; 16]); 319 320 impl Deref for Uuid { 321 type Target = [u8; 16]; 322 deref(&self) -> &Self::Target323 fn deref(&self) -> &Self::Target { 324 &self.0 325 } 326 } 327 328 impl From<SecurityLevel> for Uuid { from(sec_level: SecurityLevel) -> Self329 fn from(sec_level: SecurityLevel) -> Self { 330 Self((sec_level.0 as u128).to_be_bytes()) 331 } 332 } 333 334 impl ToSql for Uuid { to_sql(&self) -> rusqlite::Result<ToSqlOutput>335 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 336 self.0.to_sql() 337 } 338 } 339 340 impl FromSql for Uuid { column_result(value: ValueRef<'_>) -> FromSqlResult<Self>341 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { 342 let blob = Vec::<u8>::column_result(value)?; 343 if blob.len() != 16 { 344 return Err(FromSqlError::OutOfRange(blob.len() as i64)); 345 } 346 let mut arr = [0u8; 16]; 347 arr.copy_from_slice(&blob); 348 Ok(Self(arr)) 349 } 350 } 351 352 /// Key entries that are not associated with any KeyMint instance, such as pure certificate 353 /// entries are associated with this UUID. 354 pub static KEYSTORE_UUID: Uuid = Uuid([ 355 0x41, 0xe3, 0xb9, 0xce, 0x27, 0x58, 0x4e, 0x91, 0xbc, 0xfd, 0xa5, 0x5d, 0x91, 0x85, 0xab, 0x11, 356 ]); 357 358 /// Indicates how the sensitive part of this key blob is encrypted. 359 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] 360 pub enum EncryptedBy { 361 /// The keyblob is encrypted by a user password. 362 /// In the database this variant is represented as NULL. 363 Password, 364 /// The keyblob is encrypted by another key with wrapped key id. 365 /// In the database this variant is represented as non NULL value 366 /// that is convertible to i64, typically NUMERIC. 367 KeyId(i64), 368 } 369 370 impl ToSql for EncryptedBy { to_sql(&self) -> rusqlite::Result<ToSqlOutput>371 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 372 match self { 373 Self::Password => Ok(ToSqlOutput::Owned(Value::Null)), 374 Self::KeyId(id) => id.to_sql(), 375 } 376 } 377 } 378 379 impl FromSql for EncryptedBy { column_result(value: ValueRef) -> FromSqlResult<Self>380 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 381 match value { 382 ValueRef::Null => Ok(Self::Password), 383 _ => Ok(Self::KeyId(i64::column_result(value)?)), 384 } 385 } 386 } 387 388 /// A database representation of wall clock time. DateTime stores unix epoch time as 389 /// i64 in milliseconds. 390 #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)] 391 pub struct DateTime(i64); 392 393 /// Error type returned when creating DateTime or converting it from and to 394 /// SystemTime. 395 #[derive(thiserror::Error, Debug)] 396 pub enum DateTimeError { 397 /// This is returned when SystemTime and Duration computations fail. 398 #[error(transparent)] 399 SystemTimeError(#[from] SystemTimeError), 400 401 /// This is returned when type conversions fail. 402 #[error(transparent)] 403 TypeConversion(#[from] std::num::TryFromIntError), 404 405 /// This is returned when checked time arithmetic failed. 406 #[error("Time arithmetic failed.")] 407 TimeArithmetic, 408 } 409 410 impl DateTime { 411 /// Constructs a new DateTime object denoting the current time. This may fail during 412 /// conversion to unix epoch time and during conversion to the internal i64 representation. now() -> Result<Self, DateTimeError>413 pub fn now() -> Result<Self, DateTimeError> { 414 Ok(Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?)) 415 } 416 417 /// Constructs a new DateTime object from milliseconds. from_millis_epoch(millis: i64) -> Self418 pub fn from_millis_epoch(millis: i64) -> Self { 419 Self(millis) 420 } 421 422 /// Returns unix epoch time in milliseconds. to_millis_epoch(self) -> i64423 pub fn to_millis_epoch(self) -> i64 { 424 self.0 425 } 426 } 427 428 impl ToSql for DateTime { to_sql(&self) -> rusqlite::Result<ToSqlOutput>429 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 430 Ok(ToSqlOutput::Owned(Value::Integer(self.0))) 431 } 432 } 433 434 impl FromSql for DateTime { column_result(value: ValueRef) -> FromSqlResult<Self>435 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 436 Ok(Self(i64::column_result(value)?)) 437 } 438 } 439 440 impl TryInto<SystemTime> for DateTime { 441 type Error = DateTimeError; 442 try_into(self) -> Result<SystemTime, Self::Error>443 fn try_into(self) -> Result<SystemTime, Self::Error> { 444 // We want to construct a SystemTime representation equivalent to self, denoting 445 // a point in time THEN, but we cannot set the time directly. We can only construct 446 // a SystemTime denoting NOW, and we can get the duration between EPOCH and NOW, 447 // and between EPOCH and THEN. With this common reference we can construct the 448 // duration between NOW and THEN which we can add to our SystemTime representation 449 // of NOW to get a SystemTime representation of THEN. 450 // Durations can only be positive, thus the if statement below. 451 let now = SystemTime::now(); 452 let now_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?; 453 let then_epoch = Duration::from_millis(self.0.try_into()?); 454 Ok(if now_epoch > then_epoch { 455 // then = now - (now_epoch - then_epoch) 456 now_epoch 457 .checked_sub(then_epoch) 458 .and_then(|d| now.checked_sub(d)) 459 .ok_or(DateTimeError::TimeArithmetic)? 460 } else { 461 // then = now + (then_epoch - now_epoch) 462 then_epoch 463 .checked_sub(now_epoch) 464 .and_then(|d| now.checked_add(d)) 465 .ok_or(DateTimeError::TimeArithmetic)? 466 }) 467 } 468 } 469 470 impl TryFrom<SystemTime> for DateTime { 471 type Error = DateTimeError; 472 try_from(t: SystemTime) -> Result<Self, Self::Error>473 fn try_from(t: SystemTime) -> Result<Self, Self::Error> { 474 Ok(Self(t.duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?)) 475 } 476 } 477 478 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] 479 enum KeyLifeCycle { 480 /// Existing keys have a key ID but are not fully populated yet. 481 /// This is a transient state. If Keystore finds any such keys when it starts up, it must move 482 /// them to Unreferenced for garbage collection. 483 Existing, 484 /// A live key is fully populated and usable by clients. 485 Live, 486 /// An unreferenced key is scheduled for garbage collection. 487 Unreferenced, 488 } 489 490 impl ToSql for KeyLifeCycle { to_sql(&self) -> rusqlite::Result<ToSqlOutput>491 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 492 match self { 493 Self::Existing => Ok(ToSqlOutput::Owned(Value::Integer(0))), 494 Self::Live => Ok(ToSqlOutput::Owned(Value::Integer(1))), 495 Self::Unreferenced => Ok(ToSqlOutput::Owned(Value::Integer(2))), 496 } 497 } 498 } 499 500 impl FromSql for KeyLifeCycle { column_result(value: ValueRef) -> FromSqlResult<Self>501 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 502 match i64::column_result(value)? { 503 0 => Ok(KeyLifeCycle::Existing), 504 1 => Ok(KeyLifeCycle::Live), 505 2 => Ok(KeyLifeCycle::Unreferenced), 506 v => Err(FromSqlError::OutOfRange(v)), 507 } 508 } 509 } 510 511 /// Current state of a `blobentry` row. 512 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Default)] 513 enum BlobState { 514 #[default] 515 /// Current blobentry (of its `subcomponent_type`) for the associated key. 516 Current, 517 /// Blobentry that is no longer the current blob (of its `subcomponent_type`) for the associated 518 /// key. 519 Superseded, 520 /// Blobentry for a key that no longer exists. 521 Orphaned, 522 } 523 524 impl ToSql for BlobState { to_sql(&self) -> rusqlite::Result<ToSqlOutput>525 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 526 match self { 527 Self::Current => Ok(ToSqlOutput::Owned(Value::Integer(0))), 528 Self::Superseded => Ok(ToSqlOutput::Owned(Value::Integer(1))), 529 Self::Orphaned => Ok(ToSqlOutput::Owned(Value::Integer(2))), 530 } 531 } 532 } 533 534 impl FromSql for BlobState { column_result(value: ValueRef) -> FromSqlResult<Self>535 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 536 match i64::column_result(value)? { 537 0 => Ok(Self::Current), 538 1 => Ok(Self::Superseded), 539 2 => Ok(Self::Orphaned), 540 v => Err(FromSqlError::OutOfRange(v)), 541 } 542 } 543 } 544 545 /// Keys have a KeyMint blob component and optional public certificate and 546 /// certificate chain components. 547 /// KeyEntryLoadBits is a bitmap that indicates to `KeystoreDB::load_key_entry` 548 /// which components shall be loaded from the database if present. 549 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] 550 pub struct KeyEntryLoadBits(u32); 551 552 impl KeyEntryLoadBits { 553 /// Indicate to `KeystoreDB::load_key_entry` that no component shall be loaded. 554 pub const NONE: KeyEntryLoadBits = Self(0); 555 /// Indicate to `KeystoreDB::load_key_entry` that the KeyMint component shall be loaded. 556 pub const KM: KeyEntryLoadBits = Self(1); 557 /// Indicate to `KeystoreDB::load_key_entry` that the Public components shall be loaded. 558 pub const PUBLIC: KeyEntryLoadBits = Self(2); 559 /// Indicate to `KeystoreDB::load_key_entry` that both components shall be loaded. 560 pub const BOTH: KeyEntryLoadBits = Self(3); 561 562 /// Returns true if this object indicates that the public components shall be loaded. load_public(&self) -> bool563 pub const fn load_public(&self) -> bool { 564 self.0 & Self::PUBLIC.0 != 0 565 } 566 567 /// Returns true if the object indicates that the KeyMint component shall be loaded. load_km(&self) -> bool568 pub const fn load_km(&self) -> bool { 569 self.0 & Self::KM.0 != 0 570 } 571 } 572 573 static KEY_ID_LOCK: LazyLock<KeyIdLockDb> = LazyLock::new(KeyIdLockDb::new); 574 575 struct KeyIdLockDb { 576 locked_keys: Mutex<HashSet<i64>>, 577 cond_var: Condvar, 578 } 579 580 /// A locked key. While a guard exists for a given key id, the same key cannot be loaded 581 /// from the database a second time. Most functions manipulating the key blob database 582 /// require a KeyIdGuard. 583 #[derive(Debug)] 584 pub struct KeyIdGuard(i64); 585 586 impl KeyIdLockDb { new() -> Self587 fn new() -> Self { 588 Self { locked_keys: Mutex::new(HashSet::new()), cond_var: Condvar::new() } 589 } 590 591 /// This function blocks until an exclusive lock for the given key entry id can 592 /// be acquired. It returns a guard object, that represents the lifecycle of the 593 /// acquired lock. get(&self, key_id: i64) -> KeyIdGuard594 fn get(&self, key_id: i64) -> KeyIdGuard { 595 let mut locked_keys = self.locked_keys.lock().unwrap(); 596 while locked_keys.contains(&key_id) { 597 locked_keys = self.cond_var.wait(locked_keys).unwrap(); 598 } 599 locked_keys.insert(key_id); 600 KeyIdGuard(key_id) 601 } 602 603 /// This function attempts to acquire an exclusive lock on a given key id. If the 604 /// given key id is already taken the function returns None immediately. If a lock 605 /// can be acquired this function returns a guard object, that represents the 606 /// lifecycle of the acquired lock. try_get(&self, key_id: i64) -> Option<KeyIdGuard>607 fn try_get(&self, key_id: i64) -> Option<KeyIdGuard> { 608 let mut locked_keys = self.locked_keys.lock().unwrap(); 609 if locked_keys.insert(key_id) { 610 Some(KeyIdGuard(key_id)) 611 } else { 612 None 613 } 614 } 615 } 616 617 impl KeyIdGuard { 618 /// Get the numeric key id of the locked key. id(&self) -> i64619 pub fn id(&self) -> i64 { 620 self.0 621 } 622 } 623 624 impl Drop for KeyIdGuard { drop(&mut self)625 fn drop(&mut self) { 626 let mut locked_keys = KEY_ID_LOCK.locked_keys.lock().unwrap(); 627 locked_keys.remove(&self.0); 628 drop(locked_keys); 629 KEY_ID_LOCK.cond_var.notify_all(); 630 } 631 } 632 633 /// This type represents a certificate and certificate chain entry for a key. 634 #[derive(Debug, Default)] 635 pub struct CertificateInfo { 636 cert: Option<Vec<u8>>, 637 cert_chain: Option<Vec<u8>>, 638 } 639 640 /// This type represents a Blob with its metadata and an optional superseded blob. 641 #[derive(Debug)] 642 pub struct BlobInfo<'a> { 643 blob: &'a [u8], 644 metadata: &'a BlobMetaData, 645 /// Superseded blobs are an artifact of legacy import. In some rare occasions 646 /// the key blob needs to be upgraded during import. In that case two 647 /// blob are imported, the superseded one will have to be imported first, 648 /// so that the garbage collector can reap it. 649 superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>, 650 } 651 652 impl<'a> BlobInfo<'a> { 653 /// Create a new instance of blob info with blob and corresponding metadata 654 /// and no superseded blob info. new(blob: &'a [u8], metadata: &'a BlobMetaData) -> Self655 pub fn new(blob: &'a [u8], metadata: &'a BlobMetaData) -> Self { 656 Self { blob, metadata, superseded_blob: None } 657 } 658 659 /// Create a new instance of blob info with blob and corresponding metadata 660 /// as well as superseded blob info. new_with_superseded( blob: &'a [u8], metadata: &'a BlobMetaData, superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>, ) -> Self661 pub fn new_with_superseded( 662 blob: &'a [u8], 663 metadata: &'a BlobMetaData, 664 superseded_blob: Option<(&'a [u8], &'a BlobMetaData)>, 665 ) -> Self { 666 Self { blob, metadata, superseded_blob } 667 } 668 } 669 670 impl CertificateInfo { 671 /// Constructs a new CertificateInfo object from `cert` and `cert_chain` new(cert: Option<Vec<u8>>, cert_chain: Option<Vec<u8>>) -> Self672 pub fn new(cert: Option<Vec<u8>>, cert_chain: Option<Vec<u8>>) -> Self { 673 Self { cert, cert_chain } 674 } 675 676 /// Take the cert take_cert(&mut self) -> Option<Vec<u8>>677 pub fn take_cert(&mut self) -> Option<Vec<u8>> { 678 self.cert.take() 679 } 680 681 /// Take the cert chain take_cert_chain(&mut self) -> Option<Vec<u8>>682 pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> { 683 self.cert_chain.take() 684 } 685 } 686 687 /// This type represents a certificate chain with a private key corresponding to the leaf 688 /// certificate. TODO(jbires): This will be used in a follow-on CL, for now it's used in the tests. 689 pub struct CertificateChain { 690 /// A KM key blob 691 pub private_key: ZVec, 692 /// A batch cert for private_key 693 pub batch_cert: Vec<u8>, 694 /// A full certificate chain from root signing authority to private_key, including batch_cert 695 /// for convenience. 696 pub cert_chain: Vec<u8>, 697 } 698 699 /// This type represents a Keystore 2.0 key entry. 700 /// An entry has a unique `id` by which it can be found in the database. 701 /// It has a security level field, key parameters, and three optional fields 702 /// for the KeyMint blob, public certificate and a public certificate chain. 703 #[derive(Debug, Default, Eq, PartialEq)] 704 pub struct KeyEntry { 705 id: i64, 706 key_blob_info: Option<(Vec<u8>, BlobMetaData)>, 707 cert: Option<Vec<u8>>, 708 cert_chain: Option<Vec<u8>>, 709 km_uuid: Uuid, 710 parameters: Vec<KeyParameter>, 711 metadata: KeyMetaData, 712 pure_cert: bool, 713 } 714 715 impl KeyEntry { 716 /// Returns the unique id of the Key entry. id(&self) -> i64717 pub fn id(&self) -> i64 { 718 self.id 719 } 720 /// Exposes the optional KeyMint blob. key_blob_info(&self) -> &Option<(Vec<u8>, BlobMetaData)>721 pub fn key_blob_info(&self) -> &Option<(Vec<u8>, BlobMetaData)> { 722 &self.key_blob_info 723 } 724 /// Extracts the Optional KeyMint blob including its metadata. take_key_blob_info(&mut self) -> Option<(Vec<u8>, BlobMetaData)>725 pub fn take_key_blob_info(&mut self) -> Option<(Vec<u8>, BlobMetaData)> { 726 self.key_blob_info.take() 727 } 728 /// Exposes the optional public certificate. cert(&self) -> &Option<Vec<u8>>729 pub fn cert(&self) -> &Option<Vec<u8>> { 730 &self.cert 731 } 732 /// Extracts the optional public certificate. take_cert(&mut self) -> Option<Vec<u8>>733 pub fn take_cert(&mut self) -> Option<Vec<u8>> { 734 self.cert.take() 735 } 736 /// Extracts the optional public certificate_chain. take_cert_chain(&mut self) -> Option<Vec<u8>>737 pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> { 738 self.cert_chain.take() 739 } 740 /// Returns the uuid of the owning KeyMint instance. km_uuid(&self) -> &Uuid741 pub fn km_uuid(&self) -> &Uuid { 742 &self.km_uuid 743 } 744 /// Consumes this key entry and extracts the keyparameters from it. into_key_parameters(self) -> Vec<KeyParameter>745 pub fn into_key_parameters(self) -> Vec<KeyParameter> { 746 self.parameters 747 } 748 /// Exposes the key metadata of this key entry. metadata(&self) -> &KeyMetaData749 pub fn metadata(&self) -> &KeyMetaData { 750 &self.metadata 751 } 752 /// This returns true if the entry is a pure certificate entry with no 753 /// private key component. pure_cert(&self) -> bool754 pub fn pure_cert(&self) -> bool { 755 self.pure_cert 756 } 757 } 758 759 /// Indicates the sub component of a key entry for persistent storage. 760 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] 761 pub struct SubComponentType(u32); 762 impl SubComponentType { 763 /// Persistent identifier for a key blob. 764 pub const KEY_BLOB: SubComponentType = Self(0); 765 /// Persistent identifier for a certificate blob. 766 pub const CERT: SubComponentType = Self(1); 767 /// Persistent identifier for a certificate chain blob. 768 pub const CERT_CHAIN: SubComponentType = Self(2); 769 } 770 771 impl ToSql for SubComponentType { to_sql(&self) -> rusqlite::Result<ToSqlOutput>772 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 773 self.0.to_sql() 774 } 775 } 776 777 impl FromSql for SubComponentType { column_result(value: ValueRef) -> FromSqlResult<Self>778 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 779 Ok(Self(u32::column_result(value)?)) 780 } 781 } 782 783 /// This trait is private to the database module. It is used to convey whether or not the garbage 784 /// collector shall be invoked after a database access. All closures passed to 785 /// `KeystoreDB::with_transaction` return a tuple (bool, T) where the bool indicates if the 786 /// gc needs to be triggered. This convenience function allows to turn any anyhow::Result<T> 787 /// into anyhow::Result<(bool, T)> by simply appending one of `.do_gc(bool)`, `.no_gc()`, or 788 /// `.need_gc()`. 789 trait DoGc<T> { do_gc(self, need_gc: bool) -> Result<(bool, T)>790 fn do_gc(self, need_gc: bool) -> Result<(bool, T)>; 791 no_gc(self) -> Result<(bool, T)>792 fn no_gc(self) -> Result<(bool, T)>; 793 need_gc(self) -> Result<(bool, T)>794 fn need_gc(self) -> Result<(bool, T)>; 795 } 796 797 impl<T> DoGc<T> for Result<T> { do_gc(self, need_gc: bool) -> Result<(bool, T)>798 fn do_gc(self, need_gc: bool) -> Result<(bool, T)> { 799 self.map(|r| (need_gc, r)) 800 } 801 no_gc(self) -> Result<(bool, T)>802 fn no_gc(self) -> Result<(bool, T)> { 803 self.do_gc(false) 804 } 805 need_gc(self) -> Result<(bool, T)>806 fn need_gc(self) -> Result<(bool, T)> { 807 self.do_gc(true) 808 } 809 } 810 811 /// KeystoreDB wraps a connection to an SQLite database and tracks its 812 /// ownership. It also implements all of Keystore 2.0's database functionality. 813 pub struct KeystoreDB { 814 conn: Connection, 815 gc: Option<Arc<Gc>>, 816 perboot: Arc<perboot::PerbootDB>, 817 } 818 819 /// Database representation of the monotonic time retrieved from the system call clock_gettime with 820 /// CLOCK_BOOTTIME. Stores monotonic time as i64 in milliseconds. 821 #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)] 822 pub struct BootTime(i64); 823 824 impl BootTime { 825 /// Constructs a new BootTime now() -> Self826 pub fn now() -> Self { 827 Self(get_current_time_in_milliseconds()) 828 } 829 830 /// Returns the value of BootTime in milliseconds as i64 milliseconds(&self) -> i64831 pub fn milliseconds(&self) -> i64 { 832 self.0 833 } 834 835 /// Returns the integer value of BootTime as i64 seconds(&self) -> i64836 pub fn seconds(&self) -> i64 { 837 self.0 / 1000 838 } 839 840 /// Like i64::checked_sub. checked_sub(&self, other: &Self) -> Option<Self>841 pub fn checked_sub(&self, other: &Self) -> Option<Self> { 842 self.0.checked_sub(other.0).map(Self) 843 } 844 } 845 846 impl ToSql for BootTime { to_sql(&self) -> rusqlite::Result<ToSqlOutput>847 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> { 848 Ok(ToSqlOutput::Owned(Value::Integer(self.0))) 849 } 850 } 851 852 impl FromSql for BootTime { column_result(value: ValueRef) -> FromSqlResult<Self>853 fn column_result(value: ValueRef) -> FromSqlResult<Self> { 854 Ok(Self(i64::column_result(value)?)) 855 } 856 } 857 858 /// This struct encapsulates the information to be stored in the database about the auth tokens 859 /// received by keystore. 860 #[derive(Clone)] 861 pub struct AuthTokenEntry { 862 auth_token: HardwareAuthToken, 863 // Time received in milliseconds 864 time_received: BootTime, 865 } 866 867 impl AuthTokenEntry { new(auth_token: HardwareAuthToken, time_received: BootTime) -> Self868 fn new(auth_token: HardwareAuthToken, time_received: BootTime) -> Self { 869 AuthTokenEntry { auth_token, time_received } 870 } 871 872 /// Checks if this auth token satisfies the given authentication information. satisfies(&self, user_secure_ids: &[i64], auth_type: HardwareAuthenticatorType) -> bool873 pub fn satisfies(&self, user_secure_ids: &[i64], auth_type: HardwareAuthenticatorType) -> bool { 874 user_secure_ids.iter().any(|&sid| { 875 (sid == self.auth_token.userId || sid == self.auth_token.authenticatorId) 876 && ((auth_type.0 & self.auth_token.authenticatorType.0) != 0) 877 }) 878 } 879 880 /// Returns the auth token wrapped by the AuthTokenEntry auth_token(&self) -> &HardwareAuthToken881 pub fn auth_token(&self) -> &HardwareAuthToken { 882 &self.auth_token 883 } 884 885 /// Returns the auth token wrapped by the AuthTokenEntry take_auth_token(self) -> HardwareAuthToken886 pub fn take_auth_token(self) -> HardwareAuthToken { 887 self.auth_token 888 } 889 890 /// Returns the time that this auth token was received. time_received(&self) -> BootTime891 pub fn time_received(&self) -> BootTime { 892 self.time_received 893 } 894 895 /// Returns the challenge value of the auth token. challenge(&self) -> i64896 pub fn challenge(&self) -> i64 { 897 self.auth_token.challenge 898 } 899 } 900 901 /// Information about a superseded blob (a blob that is no longer the 902 /// most recent blob of that type for a given key, due to upgrade or 903 /// replacement). 904 pub struct SupersededBlob { 905 /// ID 906 pub blob_id: i64, 907 /// Contents. 908 pub blob: Vec<u8>, 909 /// Metadata. 910 pub metadata: BlobMetaData, 911 } 912 913 impl KeystoreDB { 914 const UNASSIGNED_KEY_ID: i64 = -1i64; 915 const CURRENT_DB_VERSION: u32 = 2; 916 const UPGRADERS: &'static [fn(&Transaction) -> Result<u32>] = 917 &[Self::from_0_to_1, Self::from_1_to_2]; 918 919 /// Name of the file that holds the cross-boot persistent database. 920 pub const PERSISTENT_DB_FILENAME: &'static str = "persistent.sqlite"; 921 922 /// This will create a new database connection connecting the two 923 /// files persistent.sqlite and perboot.sqlite in the given directory. 924 /// It also attempts to initialize all of the tables. 925 /// KeystoreDB cannot be used by multiple threads. 926 /// Each thread should open their own connection using `thread_local!`. new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self>927 pub fn new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self> { 928 let _wp = wd::watch("KeystoreDB::new"); 929 930 let persistent_path = Self::make_persistent_path(db_root)?; 931 let conn = Self::make_connection(&persistent_path)?; 932 933 let mut db = Self { conn, gc, perboot: perboot::PERBOOT_DB.clone() }; 934 db.with_transaction(Immediate("TX_new"), |tx| { 935 versioning::upgrade_database(tx, Self::CURRENT_DB_VERSION, Self::UPGRADERS) 936 .context(ks_err!("KeystoreDB::new: trying to upgrade database."))?; 937 Self::init_tables(tx).context("Trying to initialize tables.").no_gc() 938 })?; 939 Ok(db) 940 } 941 942 // This upgrade function deletes all MAX_BOOT_LEVEL keys, that were generated before 943 // cryptographic binding to the boot level keys was implemented. from_0_to_1(tx: &Transaction) -> Result<u32>944 fn from_0_to_1(tx: &Transaction) -> Result<u32> { 945 tx.execute( 946 "UPDATE persistent.keyentry SET state = ? 947 WHERE 948 id IN (SELECT keyentryid FROM persistent.keyparameter WHERE tag = ?) 949 AND 950 id NOT IN ( 951 SELECT keyentryid FROM persistent.blobentry 952 WHERE id IN ( 953 SELECT blobentryid FROM persistent.blobmetadata WHERE tag = ? 954 ) 955 );", 956 params![KeyLifeCycle::Unreferenced, Tag::MAX_BOOT_LEVEL.0, BlobMetaData::MaxBootLevel], 957 ) 958 .context(ks_err!("Failed to delete logical boot level keys."))?; 959 960 // DB version is now 1. 961 Ok(1) 962 } 963 964 // This upgrade function adds an additional `state INTEGER` column to the blobentry 965 // table, and populates it based on whether each blob is the most recent of its type for 966 // the corresponding key. from_1_to_2(tx: &Transaction) -> Result<u32>967 fn from_1_to_2(tx: &Transaction) -> Result<u32> { 968 tx.execute( 969 "ALTER TABLE persistent.blobentry ADD COLUMN state INTEGER DEFAULT 0;", 970 params![], 971 ) 972 .context(ks_err!("Failed to add state column"))?; 973 974 // Mark keyblobs that are not the most recent for their corresponding key. 975 // This may take a while if there are excessive numbers of keys in the database. 976 let _wp = wd::watch("KeystoreDB::from_1_to_2 mark all non-current keyblobs"); 977 let sc_key_blob = SubComponentType::KEY_BLOB; 978 let mut stmt = tx 979 .prepare( 980 "UPDATE persistent.blobentry SET state=? 981 WHERE subcomponent_type = ? 982 AND id NOT IN ( 983 SELECT MAX(id) FROM persistent.blobentry 984 WHERE subcomponent_type = ? 985 GROUP BY keyentryid, subcomponent_type 986 );", 987 ) 988 .context("Trying to prepare query to mark superseded keyblobs")?; 989 stmt.execute(params![BlobState::Superseded, sc_key_blob, sc_key_blob]) 990 .context(ks_err!("Failed to set state=superseded state for keyblobs"))?; 991 log::info!("marked non-current blobentry rows for keyblobs as superseded"); 992 993 // Mark keyblobs that don't have a corresponding key. 994 // This may take a while if there are excessive numbers of keys in the database. 995 let _wp = wd::watch("KeystoreDB::from_1_to_2 mark all orphaned keyblobs"); 996 let mut stmt = tx 997 .prepare( 998 "UPDATE persistent.blobentry SET state=? 999 WHERE subcomponent_type = ? 1000 AND NOT EXISTS (SELECT id FROM persistent.keyentry 1001 WHERE id = keyentryid);", 1002 ) 1003 .context("Trying to prepare query to mark orphaned keyblobs")?; 1004 stmt.execute(params![BlobState::Orphaned, sc_key_blob]) 1005 .context(ks_err!("Failed to set state=orphaned for keyblobs"))?; 1006 log::info!("marked orphaned blobentry rows for keyblobs"); 1007 1008 // Add an index to make it fast to find out of date blobentry rows. 1009 let _wp = wd::watch("KeystoreDB::from_1_to_2 add blobentry index"); 1010 tx.execute( 1011 "CREATE INDEX IF NOT EXISTS persistent.blobentry_state_index 1012 ON blobentry(subcomponent_type, state);", 1013 [], 1014 ) 1015 .context("Failed to create index blobentry_state_index.")?; 1016 1017 // Add an index to make it fast to find unreferenced keyentry rows. 1018 let _wp = wd::watch("KeystoreDB::from_1_to_2 add keyentry state index"); 1019 tx.execute( 1020 "CREATE INDEX IF NOT EXISTS persistent.keyentry_state_index 1021 ON keyentry(state);", 1022 [], 1023 ) 1024 .context("Failed to create index keyentry_state_index.")?; 1025 1026 // DB version is now 2. 1027 Ok(2) 1028 } 1029 init_tables(tx: &Transaction) -> Result<()>1030 fn init_tables(tx: &Transaction) -> Result<()> { 1031 tx.execute( 1032 "CREATE TABLE IF NOT EXISTS persistent.keyentry ( 1033 id INTEGER UNIQUE, 1034 key_type INTEGER, 1035 domain INTEGER, 1036 namespace INTEGER, 1037 alias BLOB, 1038 state INTEGER, 1039 km_uuid BLOB);", 1040 [], 1041 ) 1042 .context("Failed to initialize \"keyentry\" table.")?; 1043 1044 tx.execute( 1045 "CREATE INDEX IF NOT EXISTS persistent.keyentry_id_index 1046 ON keyentry(id);", 1047 [], 1048 ) 1049 .context("Failed to create index keyentry_id_index.")?; 1050 1051 tx.execute( 1052 "CREATE INDEX IF NOT EXISTS persistent.keyentry_domain_namespace_index 1053 ON keyentry(domain, namespace, alias);", 1054 [], 1055 ) 1056 .context("Failed to create index keyentry_domain_namespace_index.")?; 1057 1058 // Index added in v2 of database schema. 1059 tx.execute( 1060 "CREATE INDEX IF NOT EXISTS persistent.keyentry_state_index 1061 ON keyentry(state);", 1062 [], 1063 ) 1064 .context("Failed to create index keyentry_state_index.")?; 1065 1066 tx.execute( 1067 "CREATE TABLE IF NOT EXISTS persistent.blobentry ( 1068 id INTEGER PRIMARY KEY, 1069 subcomponent_type INTEGER, 1070 keyentryid INTEGER, 1071 blob BLOB, 1072 state INTEGER DEFAULT 0);", // `state` added in v2 of schema 1073 [], 1074 ) 1075 .context("Failed to initialize \"blobentry\" table.")?; 1076 1077 tx.execute( 1078 "CREATE INDEX IF NOT EXISTS persistent.blobentry_keyentryid_index 1079 ON blobentry(keyentryid);", 1080 [], 1081 ) 1082 .context("Failed to create index blobentry_keyentryid_index.")?; 1083 1084 // Index added in v2 of database schema. 1085 tx.execute( 1086 "CREATE INDEX IF NOT EXISTS persistent.blobentry_state_index 1087 ON blobentry(subcomponent_type, state);", 1088 [], 1089 ) 1090 .context("Failed to create index blobentry_state_index.")?; 1091 1092 tx.execute( 1093 "CREATE TABLE IF NOT EXISTS persistent.blobmetadata ( 1094 id INTEGER PRIMARY KEY, 1095 blobentryid INTEGER, 1096 tag INTEGER, 1097 data ANY, 1098 UNIQUE (blobentryid, tag));", 1099 [], 1100 ) 1101 .context("Failed to initialize \"blobmetadata\" table.")?; 1102 1103 tx.execute( 1104 "CREATE INDEX IF NOT EXISTS persistent.blobmetadata_blobentryid_index 1105 ON blobmetadata(blobentryid);", 1106 [], 1107 ) 1108 .context("Failed to create index blobmetadata_blobentryid_index.")?; 1109 1110 tx.execute( 1111 "CREATE TABLE IF NOT EXISTS persistent.keyparameter ( 1112 keyentryid INTEGER, 1113 tag INTEGER, 1114 data ANY, 1115 security_level INTEGER);", 1116 [], 1117 ) 1118 .context("Failed to initialize \"keyparameter\" table.")?; 1119 1120 tx.execute( 1121 "CREATE INDEX IF NOT EXISTS persistent.keyparameter_keyentryid_index 1122 ON keyparameter(keyentryid);", 1123 [], 1124 ) 1125 .context("Failed to create index keyparameter_keyentryid_index.")?; 1126 1127 tx.execute( 1128 "CREATE TABLE IF NOT EXISTS persistent.keymetadata ( 1129 keyentryid INTEGER, 1130 tag INTEGER, 1131 data ANY, 1132 UNIQUE (keyentryid, tag));", 1133 [], 1134 ) 1135 .context("Failed to initialize \"keymetadata\" table.")?; 1136 1137 tx.execute( 1138 "CREATE INDEX IF NOT EXISTS persistent.keymetadata_keyentryid_index 1139 ON keymetadata(keyentryid);", 1140 [], 1141 ) 1142 .context("Failed to create index keymetadata_keyentryid_index.")?; 1143 1144 tx.execute( 1145 "CREATE TABLE IF NOT EXISTS persistent.grant ( 1146 id INTEGER UNIQUE, 1147 grantee INTEGER, 1148 keyentryid INTEGER, 1149 access_vector INTEGER);", 1150 [], 1151 ) 1152 .context("Failed to initialize \"grant\" table.")?; 1153 1154 Ok(()) 1155 } 1156 make_persistent_path(db_root: &Path) -> Result<String>1157 fn make_persistent_path(db_root: &Path) -> Result<String> { 1158 // Build the path to the sqlite file. 1159 let mut persistent_path = db_root.to_path_buf(); 1160 persistent_path.push(Self::PERSISTENT_DB_FILENAME); 1161 1162 // Now convert them to strings prefixed with "file:" 1163 let mut persistent_path_str = "file:".to_owned(); 1164 persistent_path_str.push_str(&persistent_path.to_string_lossy()); 1165 1166 Ok(persistent_path_str) 1167 } 1168 make_connection(persistent_file: &str) -> Result<Connection>1169 fn make_connection(persistent_file: &str) -> Result<Connection> { 1170 let conn = 1171 Connection::open_in_memory().context("Failed to initialize SQLite connection.")?; 1172 1173 loop { 1174 if let Err(e) = conn 1175 .execute("ATTACH DATABASE ? as persistent;", params![persistent_file]) 1176 .context("Failed to attach database persistent.") 1177 { 1178 if Self::is_locked_error(&e) { 1179 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 1180 continue; 1181 } else { 1182 return Err(e); 1183 } 1184 } 1185 break; 1186 } 1187 1188 // Drop the cache size from default (2M) to 0.5M 1189 conn.execute("PRAGMA persistent.cache_size = -500;", params![]) 1190 .context("Failed to decrease cache size for persistent db")?; 1191 1192 Ok(conn) 1193 } 1194 do_table_size_query( &mut self, storage_type: MetricsStorage, query: &str, params: &[&str], ) -> Result<StorageStats>1195 fn do_table_size_query( 1196 &mut self, 1197 storage_type: MetricsStorage, 1198 query: &str, 1199 params: &[&str], 1200 ) -> Result<StorageStats> { 1201 let (total, unused) = self.with_transaction(TransactionBehavior::Deferred, |tx| { 1202 tx.query_row(query, params_from_iter(params), |row| Ok((row.get(0)?, row.get(1)?))) 1203 .with_context(|| { 1204 ks_err!("get_storage_stat: Error size of storage type {}", storage_type.0) 1205 }) 1206 .no_gc() 1207 })?; 1208 Ok(StorageStats { storage_type, size: total, unused_size: unused }) 1209 } 1210 get_total_size(&mut self) -> Result<StorageStats>1211 fn get_total_size(&mut self) -> Result<StorageStats> { 1212 self.do_table_size_query( 1213 MetricsStorage::DATABASE, 1214 "SELECT page_count * page_size, freelist_count * page_size 1215 FROM pragma_page_count('persistent'), 1216 pragma_page_size('persistent'), 1217 persistent.pragma_freelist_count();", 1218 &[], 1219 ) 1220 } 1221 get_table_size( &mut self, storage_type: MetricsStorage, schema: &str, table: &str, ) -> Result<StorageStats>1222 fn get_table_size( 1223 &mut self, 1224 storage_type: MetricsStorage, 1225 schema: &str, 1226 table: &str, 1227 ) -> Result<StorageStats> { 1228 self.do_table_size_query( 1229 storage_type, 1230 "SELECT pgsize,unused FROM dbstat(?1) 1231 WHERE name=?2 AND aggregate=TRUE;", 1232 &[schema, table], 1233 ) 1234 } 1235 1236 /// Fetches a storage statistics atom for a given storage type. For storage 1237 /// types that map to a table, information about the table's storage is 1238 /// returned. Requests for storage types that are not DB tables return None. get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats>1239 pub fn get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats> { 1240 let _wp = wd::watch_millis_with("KeystoreDB::get_storage_stat", 500, storage_type); 1241 1242 match storage_type { 1243 MetricsStorage::DATABASE => self.get_total_size(), 1244 MetricsStorage::KEY_ENTRY => { 1245 self.get_table_size(storage_type, "persistent", "keyentry") 1246 } 1247 MetricsStorage::KEY_ENTRY_ID_INDEX => { 1248 self.get_table_size(storage_type, "persistent", "keyentry_id_index") 1249 } 1250 MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX => { 1251 self.get_table_size(storage_type, "persistent", "keyentry_domain_namespace_index") 1252 } 1253 MetricsStorage::BLOB_ENTRY => { 1254 self.get_table_size(storage_type, "persistent", "blobentry") 1255 } 1256 MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX => { 1257 self.get_table_size(storage_type, "persistent", "blobentry_keyentryid_index") 1258 } 1259 MetricsStorage::KEY_PARAMETER => { 1260 self.get_table_size(storage_type, "persistent", "keyparameter") 1261 } 1262 MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX => { 1263 self.get_table_size(storage_type, "persistent", "keyparameter_keyentryid_index") 1264 } 1265 MetricsStorage::KEY_METADATA => { 1266 self.get_table_size(storage_type, "persistent", "keymetadata") 1267 } 1268 MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX => { 1269 self.get_table_size(storage_type, "persistent", "keymetadata_keyentryid_index") 1270 } 1271 MetricsStorage::GRANT => self.get_table_size(storage_type, "persistent", "grant"), 1272 MetricsStorage::AUTH_TOKEN => { 1273 // Since the table is actually a BTreeMap now, unused_size is not meaningfully 1274 // reportable 1275 // Size provided is only an approximation 1276 Ok(StorageStats { 1277 storage_type, 1278 size: (self.perboot.auth_tokens_len() * std::mem::size_of::<AuthTokenEntry>()) 1279 as i32, 1280 unused_size: 0, 1281 }) 1282 } 1283 MetricsStorage::BLOB_METADATA => { 1284 self.get_table_size(storage_type, "persistent", "blobmetadata") 1285 } 1286 MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX => { 1287 self.get_table_size(storage_type, "persistent", "blobmetadata_blobentryid_index") 1288 } 1289 _ => Err(anyhow::Error::msg(format!("Unsupported storage type: {}", storage_type.0))), 1290 } 1291 } 1292 1293 /// This function is intended to be used by the garbage collector. 1294 /// It deletes the blobs given by `blob_ids_to_delete`. It then tries to find up to `max_blobs` 1295 /// superseded key blobs that might need special handling by the garbage collector. 1296 /// If no further superseded blobs can be found it deletes all other superseded blobs that don't 1297 /// need special handling and returns None. handle_next_superseded_blobs( &mut self, blob_ids_to_delete: &[i64], max_blobs: usize, ) -> Result<Vec<SupersededBlob>>1298 pub fn handle_next_superseded_blobs( 1299 &mut self, 1300 blob_ids_to_delete: &[i64], 1301 max_blobs: usize, 1302 ) -> Result<Vec<SupersededBlob>> { 1303 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob"); 1304 self.with_transaction(Immediate("TX_handle_next_superseded_blob"), |tx| { 1305 // Delete the given blobs. 1306 for blob_id in blob_ids_to_delete { 1307 tx.execute( 1308 "DELETE FROM persistent.blobmetadata WHERE blobentryid = ?;", 1309 params![blob_id], 1310 ) 1311 .context(ks_err!("Trying to delete blob metadata: {:?}", blob_id))?; 1312 tx.execute("DELETE FROM persistent.blobentry WHERE id = ?;", params![blob_id]) 1313 .context(ks_err!("Trying to delete blob: {:?}", blob_id))?; 1314 } 1315 1316 Self::cleanup_unreferenced(tx).context("Trying to cleanup unreferenced.")?; 1317 1318 // Find up to `max_blobs` more out-of-date key blobs, load their metadata and return it. 1319 let result: Vec<(i64, Vec<u8>)> = if keystore2_flags::use_blob_state_column() { 1320 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob find_next v2"); 1321 let mut stmt = tx 1322 .prepare( 1323 "SELECT id, blob FROM persistent.blobentry 1324 WHERE subcomponent_type = ? AND state != ? 1325 LIMIT ?;", 1326 ) 1327 .context("Trying to prepare query for superseded blobs.")?; 1328 1329 let rows = stmt 1330 .query_map( 1331 params![SubComponentType::KEY_BLOB, BlobState::Current, max_blobs as i64], 1332 |row| Ok((row.get(0)?, row.get(1)?)), 1333 ) 1334 .context("Trying to query superseded blob.")?; 1335 1336 rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>() 1337 .context("Trying to extract superseded blobs.")? 1338 } else { 1339 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob find_next v1"); 1340 let mut stmt = tx 1341 .prepare( 1342 "SELECT id, blob FROM persistent.blobentry 1343 WHERE subcomponent_type = ? 1344 AND ( 1345 id NOT IN ( 1346 SELECT MAX(id) FROM persistent.blobentry 1347 WHERE subcomponent_type = ? 1348 GROUP BY keyentryid, subcomponent_type 1349 ) 1350 OR keyentryid NOT IN (SELECT id FROM persistent.keyentry) 1351 ) LIMIT ?;", 1352 ) 1353 .context("Trying to prepare query for superseded blobs.")?; 1354 1355 let rows = stmt 1356 .query_map( 1357 params![ 1358 SubComponentType::KEY_BLOB, 1359 SubComponentType::KEY_BLOB, 1360 max_blobs as i64, 1361 ], 1362 |row| Ok((row.get(0)?, row.get(1)?)), 1363 ) 1364 .context("Trying to query superseded blob.")?; 1365 1366 rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>() 1367 .context("Trying to extract superseded blobs.")? 1368 }; 1369 1370 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob load_metadata"); 1371 let result = result 1372 .into_iter() 1373 .map(|(blob_id, blob)| { 1374 Ok(SupersededBlob { 1375 blob_id, 1376 blob, 1377 metadata: BlobMetaData::load_from_db(blob_id, tx)?, 1378 }) 1379 }) 1380 .collect::<Result<Vec<_>>>() 1381 .context("Trying to load blob metadata.")?; 1382 if !result.is_empty() { 1383 return Ok(result).no_gc(); 1384 } 1385 1386 // We did not find any out-of-date key blobs, so let's remove other types of superseded 1387 // blob in one transaction. 1388 if keystore2_flags::use_blob_state_column() { 1389 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob delete v2"); 1390 tx.execute( 1391 "DELETE FROM persistent.blobentry 1392 WHERE subcomponent_type != ? AND state != ?;", 1393 params![SubComponentType::KEY_BLOB, BlobState::Current], 1394 ) 1395 .context("Trying to purge out-of-date blobs (other than keyblobs)")?; 1396 } else { 1397 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob delete v1"); 1398 tx.execute( 1399 "DELETE FROM persistent.blobentry 1400 WHERE NOT subcomponent_type = ? 1401 AND ( 1402 id NOT IN ( 1403 SELECT MAX(id) FROM persistent.blobentry 1404 WHERE NOT subcomponent_type = ? 1405 GROUP BY keyentryid, subcomponent_type 1406 ) OR keyentryid NOT IN (SELECT id FROM persistent.keyentry) 1407 );", 1408 params![SubComponentType::KEY_BLOB, SubComponentType::KEY_BLOB], 1409 ) 1410 .context("Trying to purge superseded blobs.")?; 1411 } 1412 1413 Ok(vec![]).no_gc() 1414 }) 1415 .context(ks_err!()) 1416 } 1417 1418 /// This maintenance function should be called only once before the database is used for the 1419 /// first time. It restores the invariant that `KeyLifeCycle::Existing` is a transient state. 1420 /// The function transitions all key entries from Existing to Unreferenced unconditionally and 1421 /// returns the number of rows affected. If this returns a value greater than 0, it means that 1422 /// Keystore crashed at some point during key generation. Callers may want to log such 1423 /// occurrences. 1424 /// Unlike with `mark_unreferenced`, we don't need to purge grants, because only keys that made 1425 /// it to `KeyLifeCycle::Live` may have grants. cleanup_leftovers(&mut self) -> Result<usize>1426 pub fn cleanup_leftovers(&mut self) -> Result<usize> { 1427 let _wp = wd::watch("KeystoreDB::cleanup_leftovers"); 1428 1429 self.with_transaction(Immediate("TX_cleanup_leftovers"), |tx| { 1430 tx.execute( 1431 "UPDATE persistent.keyentry SET state = ? WHERE state = ?;", 1432 params![KeyLifeCycle::Unreferenced, KeyLifeCycle::Existing], 1433 ) 1434 .context("Failed to execute query.") 1435 .need_gc() 1436 }) 1437 .context(ks_err!()) 1438 } 1439 1440 /// 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>1441 pub fn key_exists( 1442 &mut self, 1443 domain: Domain, 1444 nspace: i64, 1445 alias: &str, 1446 key_type: KeyType, 1447 ) -> Result<bool> { 1448 let _wp = wd::watch("KeystoreDB::key_exists"); 1449 1450 self.with_transaction(Immediate("TX_key_exists"), |tx| { 1451 let key_descriptor = 1452 KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None }; 1453 let result = Self::load_key_entry_id(tx, &key_descriptor, key_type); 1454 match result { 1455 Ok(_) => Ok(true), 1456 Err(error) => match error.root_cause().downcast_ref::<KsError>() { 1457 Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(false), 1458 _ => Err(error).context(ks_err!("Failed to find if the key exists.")), 1459 }, 1460 } 1461 .no_gc() 1462 }) 1463 .context(ks_err!()) 1464 } 1465 1466 /// 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>1467 pub fn store_super_key( 1468 &mut self, 1469 user_id: u32, 1470 key_type: &SuperKeyType, 1471 blob: &[u8], 1472 blob_metadata: &BlobMetaData, 1473 key_metadata: &KeyMetaData, 1474 ) -> Result<KeyEntry> { 1475 let _wp = wd::watch("KeystoreDB::store_super_key"); 1476 1477 self.with_transaction(Immediate("TX_store_super_key"), |tx| { 1478 let key_id = Self::insert_with_retry(|id| { 1479 tx.execute( 1480 "INSERT into persistent.keyentry 1481 (id, key_type, domain, namespace, alias, state, km_uuid) 1482 VALUES(?, ?, ?, ?, ?, ?, ?);", 1483 params![ 1484 id, 1485 KeyType::Super, 1486 Domain::APP.0, 1487 user_id as i64, 1488 key_type.alias, 1489 KeyLifeCycle::Live, 1490 &KEYSTORE_UUID, 1491 ], 1492 ) 1493 }) 1494 .context("Failed to insert into keyentry table.")?; 1495 1496 key_metadata.store_in_db(key_id, tx).context("KeyMetaData::store_in_db failed")?; 1497 1498 Self::set_blob_internal( 1499 tx, 1500 key_id, 1501 SubComponentType::KEY_BLOB, 1502 Some(blob), 1503 Some(blob_metadata), 1504 ) 1505 .context("Failed to store key blob.")?; 1506 1507 Self::load_key_components(tx, KeyEntryLoadBits::KM, key_id) 1508 .context("Trying to load key components.") 1509 .no_gc() 1510 }) 1511 .context(ks_err!()) 1512 } 1513 1514 /// Loads super key of a given user, if exists load_super_key( &mut self, key_type: &SuperKeyType, user_id: u32, ) -> Result<Option<(KeyIdGuard, KeyEntry)>>1515 pub fn load_super_key( 1516 &mut self, 1517 key_type: &SuperKeyType, 1518 user_id: u32, 1519 ) -> Result<Option<(KeyIdGuard, KeyEntry)>> { 1520 let _wp = wd::watch("KeystoreDB::load_super_key"); 1521 1522 self.with_transaction(Immediate("TX_load_super_key"), |tx| { 1523 let key_descriptor = KeyDescriptor { 1524 domain: Domain::APP, 1525 nspace: user_id as i64, 1526 alias: Some(key_type.alias.into()), 1527 blob: None, 1528 }; 1529 let id = Self::load_key_entry_id(tx, &key_descriptor, KeyType::Super); 1530 match id { 1531 Ok(id) => { 1532 let key_entry = Self::load_key_components(tx, KeyEntryLoadBits::KM, id) 1533 .context(ks_err!("Failed to load key entry."))?; 1534 Ok(Some((KEY_ID_LOCK.get(id), key_entry))) 1535 } 1536 Err(error) => match error.root_cause().downcast_ref::<KsError>() { 1537 Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None), 1538 _ => Err(error).context(ks_err!()), 1539 }, 1540 } 1541 .no_gc() 1542 }) 1543 .context(ks_err!()) 1544 } 1545 1546 /// Creates a transaction with the given behavior and executes f with the new transaction. 1547 /// The transaction is committed only if f returns Ok and retried if DatabaseBusy 1548 /// or DatabaseLocked is encountered. with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T> where F: Fn(&Transaction) -> Result<(bool, T)>,1549 fn with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T> 1550 where 1551 F: Fn(&Transaction) -> Result<(bool, T)>, 1552 { 1553 let name = behavior.name(); 1554 loop { 1555 let result = self 1556 .conn 1557 .transaction_with_behavior(behavior.into()) 1558 .context(ks_err!()) 1559 .and_then(|tx| { 1560 let _wp = name.map(wd::watch); 1561 f(&tx).map(|result| (result, tx)) 1562 }) 1563 .and_then(|(result, tx)| { 1564 tx.commit().context(ks_err!("Failed to commit transaction."))?; 1565 Ok(result) 1566 }); 1567 match result { 1568 Ok(result) => break Ok(result), 1569 Err(e) => { 1570 if Self::is_locked_error(&e) { 1571 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 1572 continue; 1573 } else { 1574 return Err(e).context(ks_err!()); 1575 } 1576 } 1577 } 1578 } 1579 .map(|(need_gc, result)| { 1580 if need_gc { 1581 if let Some(ref gc) = self.gc { 1582 gc.notify_gc(); 1583 } 1584 } 1585 result 1586 }) 1587 } 1588 is_locked_error(e: &anyhow::Error) -> bool1589 fn is_locked_error(e: &anyhow::Error) -> bool { 1590 matches!( 1591 e.root_cause().downcast_ref::<rusqlite::ffi::Error>(), 1592 Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) 1593 | Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseLocked, .. }) 1594 ) 1595 } 1596 create_key_entry_internal( tx: &Transaction, domain: &Domain, namespace: &i64, key_type: KeyType, km_uuid: &Uuid, ) -> Result<KeyIdGuard>1597 fn create_key_entry_internal( 1598 tx: &Transaction, 1599 domain: &Domain, 1600 namespace: &i64, 1601 key_type: KeyType, 1602 km_uuid: &Uuid, 1603 ) -> Result<KeyIdGuard> { 1604 match *domain { 1605 Domain::APP | Domain::SELINUX => {} 1606 _ => { 1607 return Err(KsError::sys()) 1608 .context(ks_err!("Domain {:?} must be either App or SELinux.", domain)); 1609 } 1610 } 1611 Ok(KEY_ID_LOCK.get( 1612 Self::insert_with_retry(|id| { 1613 tx.execute( 1614 "INSERT into persistent.keyentry 1615 (id, key_type, domain, namespace, alias, state, km_uuid) 1616 VALUES(?, ?, ?, ?, NULL, ?, ?);", 1617 params![ 1618 id, 1619 key_type, 1620 domain.0 as u32, 1621 *namespace, 1622 KeyLifeCycle::Existing, 1623 km_uuid, 1624 ], 1625 ) 1626 }) 1627 .context(ks_err!())?, 1628 )) 1629 } 1630 1631 /// Set a new blob and associates it with the given key id. Each blob 1632 /// has a sub component type. 1633 /// Each key can have one of each sub component type associated. If more 1634 /// are added only the most recent can be retrieved, and superseded blobs 1635 /// will get garbage collected. 1636 /// Components SubComponentType::CERT and SubComponentType::CERT_CHAIN can be 1637 /// removed by setting blob to None. set_blob( &mut self, key_id: &KeyIdGuard, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1638 pub fn set_blob( 1639 &mut self, 1640 key_id: &KeyIdGuard, 1641 sc_type: SubComponentType, 1642 blob: Option<&[u8]>, 1643 blob_metadata: Option<&BlobMetaData>, 1644 ) -> Result<()> { 1645 let _wp = wd::watch("KeystoreDB::set_blob"); 1646 1647 self.with_transaction(Immediate("TX_set_blob"), |tx| { 1648 Self::set_blob_internal(tx, key_id.0, sc_type, blob, blob_metadata).need_gc() 1649 }) 1650 .context(ks_err!()) 1651 } 1652 1653 /// Why would we insert a deleted blob? This weird function is for the purpose of legacy 1654 /// key migration in the case where we bulk delete all the keys of an app or even a user. 1655 /// We use this to insert key blobs into the database which can then be garbage collected 1656 /// lazily by the key garbage collector. set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()>1657 pub fn set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()> { 1658 let _wp = wd::watch("KeystoreDB::set_deleted_blob"); 1659 1660 self.with_transaction(Immediate("TX_set_deleted_blob"), |tx| { 1661 Self::set_blob_internal( 1662 tx, 1663 Self::UNASSIGNED_KEY_ID, 1664 SubComponentType::KEY_BLOB, 1665 Some(blob), 1666 Some(blob_metadata), 1667 ) 1668 .need_gc() 1669 }) 1670 .context(ks_err!()) 1671 } 1672 set_blob_internal( tx: &Transaction, key_id: i64, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1673 fn set_blob_internal( 1674 tx: &Transaction, 1675 key_id: i64, 1676 sc_type: SubComponentType, 1677 blob: Option<&[u8]>, 1678 blob_metadata: Option<&BlobMetaData>, 1679 ) -> Result<()> { 1680 match (blob, sc_type) { 1681 (Some(blob), _) => { 1682 // Mark any previous blobentry(s) of the same type for the same key as superseded. 1683 tx.execute( 1684 "UPDATE persistent.blobentry SET state = ? 1685 WHERE keyentryid = ? AND subcomponent_type = ?", 1686 params![BlobState::Superseded, key_id, sc_type], 1687 ) 1688 .context(ks_err!( 1689 "Failed to mark prior {sc_type:?} blobentrys for {key_id} as superseded" 1690 ))?; 1691 1692 // Now insert the new, un-superseded, blob. (If this fails, the marking of 1693 // old blobs as superseded will be rolled back, because we're inside a 1694 // transaction.) 1695 tx.execute( 1696 "INSERT INTO persistent.blobentry 1697 (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);", 1698 params![sc_type, key_id, blob], 1699 ) 1700 .context(ks_err!("Failed to insert blob."))?; 1701 1702 if let Some(blob_metadata) = blob_metadata { 1703 let blob_id = tx 1704 .query_row("SELECT MAX(id) FROM persistent.blobentry;", [], |row| { 1705 row.get(0) 1706 }) 1707 .context(ks_err!("Failed to get new blob id."))?; 1708 1709 blob_metadata 1710 .store_in_db(blob_id, tx) 1711 .context(ks_err!("Trying to store blob metadata."))?; 1712 } 1713 } 1714 (None, SubComponentType::CERT) | (None, SubComponentType::CERT_CHAIN) => { 1715 tx.execute( 1716 "DELETE FROM persistent.blobentry 1717 WHERE subcomponent_type = ? AND keyentryid = ?;", 1718 params![sc_type, key_id], 1719 ) 1720 .context(ks_err!("Failed to delete blob."))?; 1721 } 1722 (None, _) => { 1723 return Err(KsError::sys()) 1724 .context(ks_err!("Other blobs cannot be deleted in this way.")); 1725 } 1726 } 1727 Ok(()) 1728 } 1729 1730 /// Inserts a collection of key parameters into the `persistent.keyparameter` table 1731 /// and associates them with the given `key_id`. 1732 #[cfg(test)] insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()>1733 fn insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()> { 1734 self.with_transaction(Immediate("TX_insert_keyparameter"), |tx| { 1735 Self::insert_keyparameter_internal(tx, key_id, params).no_gc() 1736 }) 1737 .context(ks_err!()) 1738 } 1739 insert_keyparameter_internal( tx: &Transaction, key_id: &KeyIdGuard, params: &[KeyParameter], ) -> Result<()>1740 fn insert_keyparameter_internal( 1741 tx: &Transaction, 1742 key_id: &KeyIdGuard, 1743 params: &[KeyParameter], 1744 ) -> Result<()> { 1745 let mut stmt = tx 1746 .prepare( 1747 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level) 1748 VALUES (?, ?, ?, ?);", 1749 ) 1750 .context(ks_err!("Failed to prepare statement."))?; 1751 1752 for p in params.iter() { 1753 stmt.insert(params![ 1754 key_id.0, 1755 p.get_tag().0, 1756 p.key_parameter_value(), 1757 p.security_level().0 1758 ]) 1759 .with_context(|| ks_err!("Failed to insert {:?}", p))?; 1760 } 1761 Ok(()) 1762 } 1763 1764 /// Insert a set of key entry specific metadata into the database. 1765 #[cfg(test)] insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()>1766 fn insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()> { 1767 self.with_transaction(Immediate("TX_insert_key_metadata"), |tx| { 1768 metadata.store_in_db(key_id.0, tx).no_gc() 1769 }) 1770 .context(ks_err!()) 1771 } 1772 1773 /// Updates the alias column of the given key id `newid` with the given alias, 1774 /// and atomically, removes the alias, domain, and namespace from another row 1775 /// with the same alias-domain-namespace tuple if such row exits. 1776 /// Returns Ok(true) if an old key was marked unreferenced as a hint to the garbage 1777 /// collector. rebind_alias( tx: &Transaction, newid: &KeyIdGuard, alias: &str, domain: &Domain, namespace: &i64, key_type: KeyType, ) -> Result<bool>1778 fn rebind_alias( 1779 tx: &Transaction, 1780 newid: &KeyIdGuard, 1781 alias: &str, 1782 domain: &Domain, 1783 namespace: &i64, 1784 key_type: KeyType, 1785 ) -> Result<bool> { 1786 match *domain { 1787 Domain::APP | Domain::SELINUX => {} 1788 _ => { 1789 return Err(KsError::sys()) 1790 .context(ks_err!("Domain {:?} must be either App or SELinux.", domain)); 1791 } 1792 } 1793 let updated = tx 1794 .execute( 1795 "UPDATE persistent.keyentry 1796 SET alias = NULL, domain = NULL, namespace = NULL, state = ? 1797 WHERE alias = ? AND domain = ? AND namespace = ? AND key_type = ?;", 1798 params![KeyLifeCycle::Unreferenced, alias, domain.0 as u32, namespace, key_type], 1799 ) 1800 .context(ks_err!("Failed to rebind existing entry."))?; 1801 let result = tx 1802 .execute( 1803 "UPDATE persistent.keyentry 1804 SET alias = ?, state = ? 1805 WHERE id = ? AND domain = ? AND namespace = ? AND state = ? AND key_type = ?;", 1806 params![ 1807 alias, 1808 KeyLifeCycle::Live, 1809 newid.0, 1810 domain.0 as u32, 1811 *namespace, 1812 KeyLifeCycle::Existing, 1813 key_type, 1814 ], 1815 ) 1816 .context(ks_err!("Failed to set alias."))?; 1817 if result != 1 { 1818 return Err(KsError::sys()).context(ks_err!( 1819 "Expected to update a single entry but instead updated {}.", 1820 result 1821 )); 1822 } 1823 Ok(updated != 0) 1824 } 1825 1826 /// Moves the key given by KeyIdGuard to the new location at `destination`. If the destination 1827 /// 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<()>1828 pub fn migrate_key_namespace( 1829 &mut self, 1830 key_id_guard: KeyIdGuard, 1831 destination: &KeyDescriptor, 1832 caller_uid: u32, 1833 check_permission: impl Fn(&KeyDescriptor) -> Result<()>, 1834 ) -> Result<()> { 1835 let _wp = wd::watch("KeystoreDB::migrate_key_namespace"); 1836 1837 let destination = match destination.domain { 1838 Domain::APP => KeyDescriptor { nspace: caller_uid as i64, ..(*destination).clone() }, 1839 Domain::SELINUX => (*destination).clone(), 1840 domain => { 1841 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1842 .context(format!("Domain {:?} must be either APP or SELINUX.", domain)); 1843 } 1844 }; 1845 1846 // Security critical: Must return immediately on failure. Do not remove the '?'; 1847 check_permission(&destination).context(ks_err!("Trying to check permission."))?; 1848 1849 let alias = destination 1850 .alias 1851 .as_ref() 1852 .ok_or(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1853 .context(ks_err!("Alias must be specified."))?; 1854 1855 self.with_transaction(Immediate("TX_migrate_key_namespace"), |tx| { 1856 // Query the destination location. If there is a key, the migration request fails. 1857 if tx 1858 .query_row( 1859 "SELECT id FROM persistent.keyentry 1860 WHERE alias = ? AND domain = ? AND namespace = ?;", 1861 params![alias, destination.domain.0, destination.nspace], 1862 |_| Ok(()), 1863 ) 1864 .optional() 1865 .context("Failed to query destination.")? 1866 .is_some() 1867 { 1868 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1869 .context("Target already exists."); 1870 } 1871 1872 let updated = tx 1873 .execute( 1874 "UPDATE persistent.keyentry 1875 SET alias = ?, domain = ?, namespace = ? 1876 WHERE id = ?;", 1877 params![alias, destination.domain.0, destination.nspace, key_id_guard.id()], 1878 ) 1879 .context("Failed to update key entry.")?; 1880 1881 if updated != 1 { 1882 return Err(KsError::sys()) 1883 .context(format!("Update succeeded, but {} rows were updated.", updated)); 1884 } 1885 Ok(()).no_gc() 1886 }) 1887 .context(ks_err!()) 1888 } 1889 1890 /// Store a new key in a single transaction. 1891 /// The function creates a new key entry, populates the blob, key parameter, and metadata 1892 /// fields, and rebinds the given alias to the new key. 1893 /// The boolean returned is a hint for the garbage collector. If true, a key was replaced, 1894 /// is now unreferenced and needs to be collected. 1895 #[allow(clippy::too_many_arguments)] store_new_key( &mut self, key: &KeyDescriptor, key_type: KeyType, params: &[KeyParameter], blob_info: &BlobInfo, cert_info: &CertificateInfo, metadata: &KeyMetaData, km_uuid: &Uuid, ) -> Result<KeyIdGuard>1896 pub fn store_new_key( 1897 &mut self, 1898 key: &KeyDescriptor, 1899 key_type: KeyType, 1900 params: &[KeyParameter], 1901 blob_info: &BlobInfo, 1902 cert_info: &CertificateInfo, 1903 metadata: &KeyMetaData, 1904 km_uuid: &Uuid, 1905 ) -> Result<KeyIdGuard> { 1906 let _wp = wd::watch("KeystoreDB::store_new_key"); 1907 1908 let (alias, domain, namespace) = match key { 1909 KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None } 1910 | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => { 1911 (alias, key.domain, nspace) 1912 } 1913 _ => { 1914 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1915 .context(ks_err!("Need alias and domain must be APP or SELINUX.")); 1916 } 1917 }; 1918 self.with_transaction(Immediate("TX_store_new_key"), |tx| { 1919 let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid) 1920 .context("Trying to create new key entry.")?; 1921 let BlobInfo { blob, metadata: blob_metadata, superseded_blob } = *blob_info; 1922 1923 // In some occasions the key blob is already upgraded during the import. 1924 // In order to make sure it gets properly deleted it is inserted into the 1925 // database here and then immediately replaced by the superseding blob. 1926 // The garbage collector will then subject the blob to deleteKey of the 1927 // KM back end to permanently invalidate the key. 1928 let need_gc = if let Some((blob, blob_metadata)) = superseded_blob { 1929 Self::set_blob_internal( 1930 tx, 1931 key_id.id(), 1932 SubComponentType::KEY_BLOB, 1933 Some(blob), 1934 Some(blob_metadata), 1935 ) 1936 .context("Trying to insert superseded key blob.")?; 1937 true 1938 } else { 1939 false 1940 }; 1941 1942 Self::set_blob_internal( 1943 tx, 1944 key_id.id(), 1945 SubComponentType::KEY_BLOB, 1946 Some(blob), 1947 Some(blob_metadata), 1948 ) 1949 .context("Trying to insert the key blob.")?; 1950 if let Some(cert) = &cert_info.cert { 1951 Self::set_blob_internal(tx, key_id.id(), SubComponentType::CERT, Some(cert), None) 1952 .context("Trying to insert the certificate.")?; 1953 } 1954 if let Some(cert_chain) = &cert_info.cert_chain { 1955 Self::set_blob_internal( 1956 tx, 1957 key_id.id(), 1958 SubComponentType::CERT_CHAIN, 1959 Some(cert_chain), 1960 None, 1961 ) 1962 .context("Trying to insert the certificate chain.")?; 1963 } 1964 Self::insert_keyparameter_internal(tx, &key_id, params) 1965 .context("Trying to insert key parameters.")?; 1966 metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?; 1967 let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type) 1968 .context("Trying to rebind alias.")? 1969 || need_gc; 1970 Ok(key_id).do_gc(need_gc) 1971 }) 1972 .context(ks_err!()) 1973 } 1974 1975 /// Store a new certificate 1976 /// The function creates a new key entry, populates the blob field and metadata, and rebinds 1977 /// the given alias to the new cert. store_new_certificate( &mut self, key: &KeyDescriptor, key_type: KeyType, cert: &[u8], km_uuid: &Uuid, ) -> Result<KeyIdGuard>1978 pub fn store_new_certificate( 1979 &mut self, 1980 key: &KeyDescriptor, 1981 key_type: KeyType, 1982 cert: &[u8], 1983 km_uuid: &Uuid, 1984 ) -> Result<KeyIdGuard> { 1985 let _wp = wd::watch("KeystoreDB::store_new_certificate"); 1986 1987 let (alias, domain, namespace) = match key { 1988 KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None } 1989 | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => { 1990 (alias, key.domain, nspace) 1991 } 1992 _ => { 1993 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1994 .context(ks_err!("Need alias and domain must be APP or SELINUX.")); 1995 } 1996 }; 1997 self.with_transaction(Immediate("TX_store_new_certificate"), |tx| { 1998 let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid) 1999 .context("Trying to create new key entry.")?; 2000 2001 Self::set_blob_internal( 2002 tx, 2003 key_id.id(), 2004 SubComponentType::CERT_CHAIN, 2005 Some(cert), 2006 None, 2007 ) 2008 .context("Trying to insert certificate.")?; 2009 2010 let mut metadata = KeyMetaData::new(); 2011 metadata.add(KeyMetaEntry::CreationDate( 2012 DateTime::now().context("Trying to make creation time.")?, 2013 )); 2014 2015 metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?; 2016 2017 let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type) 2018 .context("Trying to rebind alias.")?; 2019 Ok(key_id).do_gc(need_gc) 2020 }) 2021 .context(ks_err!()) 2022 } 2023 2024 // Helper function loading the key_id given the key descriptor 2025 // tuple comprising domain, namespace, and alias. 2026 // Requires a valid transaction. load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64>2027 fn load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64> { 2028 let alias = key 2029 .alias 2030 .as_ref() 2031 .map_or_else(|| Err(KsError::sys()), Ok) 2032 .context("In load_key_entry_id: Alias must be specified.")?; 2033 let mut stmt = tx 2034 .prepare( 2035 "SELECT id FROM persistent.keyentry 2036 WHERE 2037 key_type = ? 2038 AND domain = ? 2039 AND namespace = ? 2040 AND alias = ? 2041 AND state = ?;", 2042 ) 2043 .context("In load_key_entry_id: Failed to select from keyentry table.")?; 2044 let mut rows = stmt 2045 .query(params![key_type, key.domain.0 as u32, key.nspace, alias, KeyLifeCycle::Live]) 2046 .context("In load_key_entry_id: Failed to read from keyentry table.")?; 2047 db_utils::with_rows_extract_one(&mut rows, |row| { 2048 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)? 2049 .get(0) 2050 .context("Failed to unpack id.") 2051 }) 2052 .context(ks_err!()) 2053 } 2054 2055 /// This helper function completes the access tuple of a key, which is required 2056 /// to perform access control. The strategy depends on the `domain` field in the 2057 /// key descriptor. 2058 /// * Domain::SELINUX: The access tuple is complete and this function only loads 2059 /// the key_id for further processing. 2060 /// * Domain::APP: Like Domain::SELINUX, but the tuple is completed by `caller_uid` 2061 /// which serves as the namespace. 2062 /// * Domain::GRANT: The grant table is queried for the `key_id` and the 2063 /// `access_vector`. 2064 /// * Domain::KEY_ID: The keyentry table is queried for the owning `domain` and 2065 /// `namespace`. 2066 /// 2067 /// In each case the information returned is sufficient to perform the access 2068 /// 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<KeyAccessInfo>2069 fn load_access_tuple( 2070 tx: &Transaction, 2071 key: &KeyDescriptor, 2072 key_type: KeyType, 2073 caller_uid: u32, 2074 ) -> Result<KeyAccessInfo> { 2075 match key.domain { 2076 // Domain App or SELinux. In this case we load the key_id from 2077 // the keyentry database for further loading of key components. 2078 // We already have the full access tuple to perform access control. 2079 // The only distinction is that we use the caller_uid instead 2080 // of the caller supplied namespace if the domain field is 2081 // Domain::APP. 2082 Domain::APP | Domain::SELINUX => { 2083 let mut access_key = key.clone(); 2084 if access_key.domain == Domain::APP { 2085 access_key.nspace = caller_uid as i64; 2086 } 2087 let key_id = Self::load_key_entry_id(tx, &access_key, key_type) 2088 .with_context(|| format!("With key.domain = {:?}.", access_key.domain))?; 2089 2090 Ok(KeyAccessInfo { key_id, descriptor: access_key, vector: None }) 2091 } 2092 2093 // Domain::GRANT. In this case we load the key_id and the access_vector 2094 // from the grant table. 2095 Domain::GRANT => { 2096 let mut stmt = tx 2097 .prepare( 2098 "SELECT keyentryid, access_vector FROM persistent.grant 2099 WHERE grantee = ? AND id = ? AND 2100 (SELECT state FROM persistent.keyentry WHERE id = keyentryid) = ?;", 2101 ) 2102 .context("Domain::GRANT prepare statement failed")?; 2103 let mut rows = stmt 2104 .query(params![caller_uid as i64, key.nspace, KeyLifeCycle::Live]) 2105 .context("Domain:Grant: query failed.")?; 2106 let (key_id, access_vector): (i64, i32) = 2107 db_utils::with_rows_extract_one(&mut rows, |row| { 2108 let r = 2109 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?; 2110 Ok(( 2111 r.get(0).context("Failed to unpack key_id.")?, 2112 r.get(1).context("Failed to unpack access_vector.")?, 2113 )) 2114 }) 2115 .context("Domain::GRANT.")?; 2116 Ok(KeyAccessInfo { 2117 key_id, 2118 descriptor: key.clone(), 2119 vector: Some(access_vector.into()), 2120 }) 2121 } 2122 2123 // Domain::KEY_ID. In this case we load the domain and namespace from the 2124 // keyentry database because we need them for access control. 2125 Domain::KEY_ID => { 2126 let (domain, namespace): (Domain, i64) = { 2127 let mut stmt = tx 2128 .prepare( 2129 "SELECT domain, namespace FROM persistent.keyentry 2130 WHERE 2131 id = ? 2132 AND state = ?;", 2133 ) 2134 .context("Domain::KEY_ID: prepare statement failed")?; 2135 let mut rows = stmt 2136 .query(params![key.nspace, KeyLifeCycle::Live]) 2137 .context("Domain::KEY_ID: query failed.")?; 2138 db_utils::with_rows_extract_one(&mut rows, |row| { 2139 let r = 2140 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?; 2141 Ok(( 2142 Domain(r.get(0).context("Failed to unpack domain.")?), 2143 r.get(1).context("Failed to unpack namespace.")?, 2144 )) 2145 }) 2146 .context("Domain::KEY_ID.")? 2147 }; 2148 2149 // We may use a key by id after loading it by grant. 2150 // In this case we have to check if the caller has a grant for this particular 2151 // key. We can skip this if we already know that the caller is the owner. 2152 // But we cannot know this if domain is anything but App. E.g. in the case 2153 // of Domain::SELINUX we have to speculatively check for grants because we have to 2154 // consult the SEPolicy before we know if the caller is the owner. 2155 let access_vector: Option<KeyPermSet> = 2156 if domain != Domain::APP || namespace != caller_uid as i64 { 2157 let access_vector: Option<i32> = tx 2158 .query_row( 2159 "SELECT access_vector FROM persistent.grant 2160 WHERE grantee = ? AND keyentryid = ?;", 2161 params![caller_uid as i64, key.nspace], 2162 |row| row.get(0), 2163 ) 2164 .optional() 2165 .context("Domain::KEY_ID: query grant failed.")?; 2166 access_vector.map(|p| p.into()) 2167 } else { 2168 None 2169 }; 2170 2171 let key_id = key.nspace; 2172 let mut access_key: KeyDescriptor = key.clone(); 2173 access_key.domain = domain; 2174 access_key.nspace = namespace; 2175 2176 Ok(KeyAccessInfo { key_id, descriptor: access_key, vector: access_vector }) 2177 } 2178 _ => Err(anyhow!(KsError::Rc(ResponseCode::INVALID_ARGUMENT))), 2179 } 2180 } 2181 load_blob_components( key_id: i64, load_bits: KeyEntryLoadBits, tx: &Transaction, ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)>2182 fn load_blob_components( 2183 key_id: i64, 2184 load_bits: KeyEntryLoadBits, 2185 tx: &Transaction, 2186 ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)> { 2187 let mut stmt = tx 2188 .prepare( 2189 "SELECT MAX(id), subcomponent_type, blob FROM persistent.blobentry 2190 WHERE keyentryid = ? GROUP BY subcomponent_type;", 2191 ) 2192 .context(ks_err!("prepare statement failed."))?; 2193 2194 let mut rows = stmt.query(params![key_id]).context(ks_err!("query failed."))?; 2195 2196 let mut key_blob: Option<(i64, Vec<u8>)> = None; 2197 let mut cert_blob: Option<Vec<u8>> = None; 2198 let mut cert_chain_blob: Option<Vec<u8>> = None; 2199 let mut has_km_blob: bool = false; 2200 db_utils::with_rows_extract_all(&mut rows, |row| { 2201 let sub_type: SubComponentType = 2202 row.get(1).context("Failed to extract subcomponent_type.")?; 2203 has_km_blob = has_km_blob || sub_type == SubComponentType::KEY_BLOB; 2204 match (sub_type, load_bits.load_public(), load_bits.load_km()) { 2205 (SubComponentType::KEY_BLOB, _, true) => { 2206 key_blob = Some(( 2207 row.get(0).context("Failed to extract key blob id.")?, 2208 row.get(2).context("Failed to extract key blob.")?, 2209 )); 2210 } 2211 (SubComponentType::CERT, true, _) => { 2212 cert_blob = 2213 Some(row.get(2).context("Failed to extract public certificate blob.")?); 2214 } 2215 (SubComponentType::CERT_CHAIN, true, _) => { 2216 cert_chain_blob = 2217 Some(row.get(2).context("Failed to extract certificate chain blob.")?); 2218 } 2219 (SubComponentType::CERT, _, _) 2220 | (SubComponentType::CERT_CHAIN, _, _) 2221 | (SubComponentType::KEY_BLOB, _, _) => {} 2222 _ => Err(KsError::sys()).context("Unknown subcomponent type.")?, 2223 } 2224 Ok(()) 2225 }) 2226 .context(ks_err!())?; 2227 2228 let blob_info = key_blob.map_or::<Result<_>, _>(Ok(None), |(blob_id, blob)| { 2229 Ok(Some(( 2230 blob, 2231 BlobMetaData::load_from_db(blob_id, tx) 2232 .context(ks_err!("Trying to load blob_metadata."))?, 2233 ))) 2234 })?; 2235 2236 Ok((has_km_blob, blob_info, cert_blob, cert_chain_blob)) 2237 } 2238 load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>>2239 fn load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>> { 2240 let mut stmt = tx 2241 .prepare( 2242 "SELECT tag, data, security_level from persistent.keyparameter 2243 WHERE keyentryid = ?;", 2244 ) 2245 .context("In load_key_parameters: prepare statement failed.")?; 2246 2247 let mut parameters: Vec<KeyParameter> = Vec::new(); 2248 2249 let mut rows = 2250 stmt.query(params![key_id]).context("In load_key_parameters: query failed.")?; 2251 db_utils::with_rows_extract_all(&mut rows, |row| { 2252 let tag = Tag(row.get(0).context("Failed to read tag.")?); 2253 let sec_level = SecurityLevel(row.get(2).context("Failed to read sec_level.")?); 2254 parameters.push( 2255 KeyParameter::new_from_sql(tag, &SqlField::new(1, row), sec_level) 2256 .context("Failed to read KeyParameter.")?, 2257 ); 2258 Ok(()) 2259 }) 2260 .context(ks_err!())?; 2261 2262 Ok(parameters) 2263 } 2264 2265 /// Decrements the usage count of a limited use key. This function first checks whether the 2266 /// usage has been exhausted, if not, decreases the usage count. If the usage count reaches 2267 /// zero, the key also gets marked unreferenced and scheduled for deletion. 2268 /// 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<()>2269 pub fn check_and_update_key_usage_count(&mut self, key_id: i64) -> Result<()> { 2270 let _wp = wd::watch("KeystoreDB::check_and_update_key_usage_count"); 2271 2272 self.with_transaction(Immediate("TX_check_and_update_key_usage_count"), |tx| { 2273 let limit: Option<i32> = tx 2274 .query_row( 2275 "SELECT data FROM persistent.keyparameter WHERE keyentryid = ? AND tag = ?;", 2276 params![key_id, Tag::USAGE_COUNT_LIMIT.0], 2277 |row| row.get(0), 2278 ) 2279 .optional() 2280 .context("Trying to load usage count")?; 2281 2282 let limit = limit 2283 .ok_or(KsError::Km(ErrorCode::INVALID_KEY_BLOB)) 2284 .context("The Key no longer exists. Key is exhausted.")?; 2285 2286 tx.execute( 2287 "UPDATE persistent.keyparameter 2288 SET data = data - 1 2289 WHERE keyentryid = ? AND tag = ? AND data > 0;", 2290 params![key_id, Tag::USAGE_COUNT_LIMIT.0], 2291 ) 2292 .context("Failed to update key usage count.")?; 2293 2294 match limit { 2295 1 => Self::mark_unreferenced(tx, key_id) 2296 .map(|need_gc| (need_gc, ())) 2297 .context("Trying to mark limited use key for deletion."), 2298 0 => Err(KsError::Km(ErrorCode::INVALID_KEY_BLOB)).context("Key is exhausted."), 2299 _ => Ok(()).no_gc(), 2300 } 2301 }) 2302 .context(ks_err!()) 2303 } 2304 2305 /// Load a key entry by the given key descriptor. 2306 /// It uses the `check_permission` callback to verify if the access is allowed 2307 /// given the key access tuple read from the database using `load_access_tuple`. 2308 /// With `load_bits` the caller may specify which blobs shall be loaded from 2309 /// 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)>2310 pub fn load_key_entry( 2311 &mut self, 2312 key: &KeyDescriptor, 2313 key_type: KeyType, 2314 load_bits: KeyEntryLoadBits, 2315 caller_uid: u32, 2316 check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2317 ) -> Result<(KeyIdGuard, KeyEntry)> { 2318 let _wp = wd::watch("KeystoreDB::load_key_entry"); 2319 2320 loop { 2321 match self.load_key_entry_internal( 2322 key, 2323 key_type, 2324 load_bits, 2325 caller_uid, 2326 &check_permission, 2327 ) { 2328 Ok(result) => break Ok(result), 2329 Err(e) => { 2330 if Self::is_locked_error(&e) { 2331 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 2332 continue; 2333 } else { 2334 return Err(e).context(ks_err!()); 2335 } 2336 } 2337 } 2338 } 2339 } 2340 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)>2341 fn load_key_entry_internal( 2342 &mut self, 2343 key: &KeyDescriptor, 2344 key_type: KeyType, 2345 load_bits: KeyEntryLoadBits, 2346 caller_uid: u32, 2347 check_permission: &impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2348 ) -> Result<(KeyIdGuard, KeyEntry)> { 2349 // KEY ID LOCK 1/2 2350 // If we got a key descriptor with a key id we can get the lock right away. 2351 // Otherwise we have to defer it until we know the key id. 2352 let key_id_guard = match key.domain { 2353 Domain::KEY_ID => Some(KEY_ID_LOCK.get(key.nspace)), 2354 _ => None, 2355 }; 2356 2357 let tx = self 2358 .conn 2359 .unchecked_transaction() 2360 .context(ks_err!("Failed to initialize transaction."))?; 2361 2362 // Load the key_id and complete the access control tuple. 2363 let access = Self::load_access_tuple(&tx, key, key_type, caller_uid).context(ks_err!())?; 2364 2365 // Perform access control. It is vital that we return here if the permission is denied. 2366 // So do not touch that '?' at the end. 2367 check_permission(&access.descriptor, access.vector).context(ks_err!())?; 2368 2369 // KEY ID LOCK 2/2 2370 // If we did not get a key id lock by now, it was because we got a key descriptor 2371 // without a key id. At this point we got the key id, so we can try and get a lock. 2372 // However, we cannot block here, because we are in the middle of the transaction. 2373 // So first we try to get the lock non blocking. If that fails, we roll back the 2374 // transaction and block until we get the lock. After we successfully got the lock, 2375 // we start a new transaction and load the access tuple again. 2376 // 2377 // We don't need to perform access control again, because we already established 2378 // that the caller had access to the given key. But we need to make sure that the 2379 // key id still exists. So we have to load the key entry by key id this time. 2380 let (key_id_guard, tx) = match key_id_guard { 2381 None => match KEY_ID_LOCK.try_get(access.key_id) { 2382 None => { 2383 // Roll back the transaction. 2384 tx.rollback().context(ks_err!("Failed to roll back transaction."))?; 2385 2386 // Block until we have a key id lock. 2387 let key_id_guard = KEY_ID_LOCK.get(access.key_id); 2388 2389 // Create a new transaction. 2390 let tx = self 2391 .conn 2392 .unchecked_transaction() 2393 .context(ks_err!("Failed to initialize transaction."))?; 2394 2395 Self::load_access_tuple( 2396 &tx, 2397 // This time we have to load the key by the retrieved key id, because the 2398 // alias may have been rebound after we rolled back the transaction. 2399 &KeyDescriptor { 2400 domain: Domain::KEY_ID, 2401 nspace: access.key_id, 2402 ..Default::default() 2403 }, 2404 key_type, 2405 caller_uid, 2406 ) 2407 .context(ks_err!("(deferred key lock)"))?; 2408 (key_id_guard, tx) 2409 } 2410 Some(l) => (l, tx), 2411 }, 2412 Some(key_id_guard) => (key_id_guard, tx), 2413 }; 2414 2415 let key_entry = 2416 Self::load_key_components(&tx, load_bits, key_id_guard.id()).context(ks_err!())?; 2417 2418 tx.commit().context(ks_err!("Failed to commit transaction."))?; 2419 2420 Ok((key_id_guard, key_entry)) 2421 } 2422 mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool>2423 fn mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool> { 2424 let updated = tx 2425 .execute("DELETE FROM persistent.keyentry WHERE id = ?;", params![key_id]) 2426 .context("Trying to delete keyentry.")?; 2427 tx.execute("DELETE FROM persistent.keymetadata WHERE keyentryid = ?;", params![key_id]) 2428 .context("Trying to delete keymetadata.")?; 2429 tx.execute("DELETE FROM persistent.keyparameter WHERE keyentryid = ?;", params![key_id]) 2430 .context("Trying to delete keyparameters.")?; 2431 tx.execute("DELETE FROM persistent.grant WHERE keyentryid = ?;", params![key_id]) 2432 .context("Trying to delete grants to other apps.")?; 2433 // The associated blobentry rows are not immediately deleted when the owning keyentry is 2434 // removed, because a KeyMint `deleteKey()` invocation is needed (specifically for the 2435 // `KEY_BLOB`). That should not be done from within the database transaction. Also, calls 2436 // to `deleteKey()` need to be delayed until the boot has completed, to avoid making 2437 // permanent changes during an OTA before the point of no return. Mark the affected rows 2438 // with `state=Orphaned` so a subsequent garbage collection can do the `deleteKey()`. 2439 tx.execute( 2440 "UPDATE persistent.blobentry SET state = ? WHERE keyentryid = ?", 2441 params![BlobState::Orphaned, key_id], 2442 ) 2443 .context("Trying to mark blobentrys as superseded")?; 2444 Ok(updated != 0) 2445 } 2446 delete_received_grants(tx: &Transaction, user_id: u32) -> Result<bool>2447 fn delete_received_grants(tx: &Transaction, user_id: u32) -> Result<bool> { 2448 let updated = tx 2449 .execute( 2450 &format!("DELETE FROM persistent.grant WHERE cast ( (grantee/{AID_USER_OFFSET}) as int) = ?;"), 2451 params![user_id], 2452 ) 2453 .context(format!( 2454 "Trying to delete grants received by user ID {:?} from other apps.", 2455 user_id 2456 ))?; 2457 Ok(updated != 0) 2458 } 2459 2460 /// Marks the given key as unreferenced and removes all of the grants to this key. 2461 /// 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<()>2462 pub fn unbind_key( 2463 &mut self, 2464 key: &KeyDescriptor, 2465 key_type: KeyType, 2466 caller_uid: u32, 2467 check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2468 ) -> Result<()> { 2469 let _wp = wd::watch("KeystoreDB::unbind_key"); 2470 2471 self.with_transaction(Immediate("TX_unbind_key"), |tx| { 2472 let access = Self::load_access_tuple(tx, key, key_type, caller_uid) 2473 .context("Trying to get access tuple.")?; 2474 2475 // Perform access control. It is vital that we return here if the permission is denied. 2476 // So do not touch that '?' at the end. 2477 check_permission(&access.descriptor, access.vector) 2478 .context("While checking permission.")?; 2479 2480 Self::mark_unreferenced(tx, access.key_id) 2481 .map(|need_gc| (need_gc, ())) 2482 .context("Trying to mark the key unreferenced.") 2483 }) 2484 .context(ks_err!()) 2485 } 2486 get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid>2487 fn get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid> { 2488 tx.query_row( 2489 "SELECT km_uuid FROM persistent.keyentry WHERE id = ?", 2490 params![key_id], 2491 |row| row.get(0), 2492 ) 2493 .context(ks_err!()) 2494 } 2495 2496 /// Delete all artifacts belonging to the namespace given by the domain-namespace tuple. 2497 /// This leaves all of the blob entries orphaned for subsequent garbage collection. unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()>2498 pub fn unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()> { 2499 let _wp = wd::watch("KeystoreDB::unbind_keys_for_namespace"); 2500 2501 if !(domain == Domain::APP || domain == Domain::SELINUX) { 2502 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!()); 2503 } 2504 self.with_transaction(Immediate("TX_unbind_keys_for_namespace"), |tx| { 2505 tx.execute( 2506 "DELETE FROM persistent.keymetadata 2507 WHERE keyentryid IN ( 2508 SELECT id FROM persistent.keyentry 2509 WHERE domain = ? AND namespace = ? AND key_type = ? 2510 );", 2511 params![domain.0, namespace, KeyType::Client], 2512 ) 2513 .context("Trying to delete keymetadata.")?; 2514 tx.execute( 2515 "DELETE FROM persistent.keyparameter 2516 WHERE keyentryid IN ( 2517 SELECT id FROM persistent.keyentry 2518 WHERE domain = ? AND namespace = ? AND key_type = ? 2519 );", 2520 params![domain.0, namespace, KeyType::Client], 2521 ) 2522 .context("Trying to delete keyparameters.")?; 2523 tx.execute( 2524 "DELETE FROM persistent.grant 2525 WHERE keyentryid IN ( 2526 SELECT id FROM persistent.keyentry 2527 WHERE domain = ? AND namespace = ? AND key_type = ? 2528 );", 2529 params![domain.0, namespace, KeyType::Client], 2530 ) 2531 .context(format!( 2532 "Trying to delete grants issued for keys in domain {:?} and namespace {:?}.", 2533 domain.0, namespace 2534 ))?; 2535 if domain == Domain::APP { 2536 // Keystore uses the UID instead of the namespace argument for Domain::APP, so we 2537 // just need to delete rows where grantee == namespace. 2538 tx.execute("DELETE FROM persistent.grant WHERE grantee = ?;", params![namespace]) 2539 .context(format!( 2540 "Trying to delete received grants for domain {:?} and namespace {:?}.", 2541 domain.0, namespace 2542 ))?; 2543 } 2544 tx.execute( 2545 "DELETE FROM persistent.keyentry 2546 WHERE domain = ? AND namespace = ? AND key_type = ?;", 2547 params![domain.0, namespace, KeyType::Client], 2548 ) 2549 .context("Trying to delete keyentry.")?; 2550 Ok(()).need_gc() 2551 }) 2552 .context(ks_err!()) 2553 } 2554 cleanup_unreferenced(tx: &Transaction) -> Result<()>2555 fn cleanup_unreferenced(tx: &Transaction) -> Result<()> { 2556 let _wp = wd::watch("KeystoreDB::cleanup_unreferenced"); 2557 { 2558 tx.execute( 2559 "DELETE FROM persistent.keymetadata 2560 WHERE keyentryid IN ( 2561 SELECT id FROM persistent.keyentry 2562 WHERE state = ? 2563 );", 2564 params![KeyLifeCycle::Unreferenced], 2565 ) 2566 .context("Trying to delete keymetadata.")?; 2567 tx.execute( 2568 "DELETE FROM persistent.keyparameter 2569 WHERE keyentryid IN ( 2570 SELECT id FROM persistent.keyentry 2571 WHERE state = ? 2572 );", 2573 params![KeyLifeCycle::Unreferenced], 2574 ) 2575 .context("Trying to delete keyparameters.")?; 2576 tx.execute( 2577 "DELETE FROM persistent.grant 2578 WHERE keyentryid IN ( 2579 SELECT id FROM persistent.keyentry 2580 WHERE state = ? 2581 );", 2582 params![KeyLifeCycle::Unreferenced], 2583 ) 2584 .context("Trying to delete grants.")?; 2585 tx.execute( 2586 "DELETE FROM persistent.keyentry 2587 WHERE state = ?;", 2588 params![KeyLifeCycle::Unreferenced], 2589 ) 2590 .context("Trying to delete keyentry.")?; 2591 Result::<()>::Ok(()) 2592 } 2593 .context(ks_err!()) 2594 } 2595 2596 /// Deletes all keys for the given user, including both client keys and super keys. unbind_keys_for_user(&mut self, user_id: u32) -> Result<()>2597 pub fn unbind_keys_for_user(&mut self, user_id: u32) -> Result<()> { 2598 let _wp = wd::watch("KeystoreDB::unbind_keys_for_user"); 2599 2600 self.with_transaction(Immediate("TX_unbind_keys_for_user"), |tx| { 2601 Self::delete_received_grants(tx, user_id).context(format!( 2602 "In unbind_keys_for_user. Failed to delete received grants for user ID {:?}.", 2603 user_id 2604 ))?; 2605 2606 let mut stmt = tx 2607 .prepare(&format!( 2608 "SELECT id from persistent.keyentry 2609 WHERE ( 2610 key_type = ? 2611 AND domain = ? 2612 AND cast ( (namespace/{aid_user_offset}) as int) = ? 2613 AND state = ? 2614 ) OR ( 2615 key_type = ? 2616 AND namespace = ? 2617 AND state = ? 2618 );", 2619 aid_user_offset = AID_USER_OFFSET 2620 )) 2621 .context(concat!( 2622 "In unbind_keys_for_user. ", 2623 "Failed to prepare the query to find the keys created by apps." 2624 ))?; 2625 2626 let mut rows = stmt 2627 .query(params![ 2628 // WHERE client key: 2629 KeyType::Client, 2630 Domain::APP.0 as u32, 2631 user_id, 2632 KeyLifeCycle::Live, 2633 // OR super key: 2634 KeyType::Super, 2635 user_id, 2636 KeyLifeCycle::Live 2637 ]) 2638 .context(ks_err!("Failed to query the keys created by apps."))?; 2639 2640 let mut key_ids: Vec<i64> = Vec::new(); 2641 db_utils::with_rows_extract_all(&mut rows, |row| { 2642 key_ids 2643 .push(row.get(0).context("Failed to read key id of a key created by an app.")?); 2644 Ok(()) 2645 }) 2646 .context(ks_err!())?; 2647 2648 let mut notify_gc = false; 2649 for key_id in key_ids { 2650 notify_gc = Self::mark_unreferenced(tx, key_id) 2651 .context("In unbind_keys_for_user. Failed to mark key id as unreferenced.")? 2652 || notify_gc; 2653 } 2654 Ok(()).do_gc(notify_gc) 2655 }) 2656 .context(ks_err!()) 2657 } 2658 2659 /// Deletes all auth-bound keys, i.e. keys that require user authentication, for the given user. 2660 /// This runs when the user's lock screen is being changed to Swipe or None. 2661 /// 2662 /// This intentionally does *not* delete keys that require that the device be unlocked, unless 2663 /// such keys also require user authentication. Keystore's concept of user authentication is 2664 /// fairly strong, and it requires that keys that require authentication be deleted as soon as 2665 /// authentication is no longer possible. In contrast, keys that just require that the device 2666 /// be unlocked should remain usable when the lock screen is set to Swipe or None, as the device 2667 /// is always considered "unlocked" in that case. unbind_auth_bound_keys_for_user(&mut self, user_id: u32) -> Result<()>2668 pub fn unbind_auth_bound_keys_for_user(&mut self, user_id: u32) -> Result<()> { 2669 let _wp = wd::watch("KeystoreDB::unbind_auth_bound_keys_for_user"); 2670 2671 self.with_transaction(Immediate("TX_unbind_auth_bound_keys_for_user"), |tx| { 2672 let mut stmt = tx 2673 .prepare(&format!( 2674 "SELECT id from persistent.keyentry 2675 WHERE key_type = ? 2676 AND domain = ? 2677 AND cast ( (namespace/{aid_user_offset}) as int) = ? 2678 AND state = ?;", 2679 aid_user_offset = AID_USER_OFFSET 2680 )) 2681 .context(concat!( 2682 "In unbind_auth_bound_keys_for_user. ", 2683 "Failed to prepare the query to find the keys created by apps." 2684 ))?; 2685 2686 let mut rows = stmt 2687 .query(params![KeyType::Client, Domain::APP.0 as u32, user_id, KeyLifeCycle::Live,]) 2688 .context(ks_err!("Failed to query the keys created by apps."))?; 2689 2690 let mut key_ids: Vec<i64> = Vec::new(); 2691 db_utils::with_rows_extract_all(&mut rows, |row| { 2692 key_ids 2693 .push(row.get(0).context("Failed to read key id of a key created by an app.")?); 2694 Ok(()) 2695 }) 2696 .context(ks_err!())?; 2697 2698 let mut notify_gc = false; 2699 let mut num_unbound = 0; 2700 for key_id in key_ids { 2701 // Load the key parameters and filter out non-auth-bound keys. To identify 2702 // auth-bound keys, use the presence of UserSecureID. The absence of NoAuthRequired 2703 // could also be used, but UserSecureID is what Keystore treats as authoritative 2704 // when actually enforcing the key parameters (it might not matter, though). 2705 let params = Self::load_key_parameters(key_id, tx) 2706 .context("Failed to load key parameters.")?; 2707 let is_auth_bound_key = params.iter().any(|kp| { 2708 matches!(kp.key_parameter_value(), KeyParameterValue::UserSecureID(_)) 2709 }); 2710 if is_auth_bound_key { 2711 notify_gc = Self::mark_unreferenced(tx, key_id) 2712 .context("In unbind_auth_bound_keys_for_user.")? 2713 || notify_gc; 2714 num_unbound += 1; 2715 } 2716 } 2717 log::info!("Deleting {num_unbound} auth-bound keys for user {user_id}"); 2718 Ok(()).do_gc(notify_gc) 2719 }) 2720 .context(ks_err!()) 2721 } 2722 load_key_components( tx: &Transaction, load_bits: KeyEntryLoadBits, key_id: i64, ) -> Result<KeyEntry>2723 fn load_key_components( 2724 tx: &Transaction, 2725 load_bits: KeyEntryLoadBits, 2726 key_id: i64, 2727 ) -> Result<KeyEntry> { 2728 let metadata = KeyMetaData::load_from_db(key_id, tx).context("In load_key_components.")?; 2729 2730 let (has_km_blob, key_blob_info, cert_blob, cert_chain_blob) = 2731 Self::load_blob_components(key_id, load_bits, tx).context("In load_key_components.")?; 2732 2733 let parameters = Self::load_key_parameters(key_id, tx) 2734 .context("In load_key_components: Trying to load key parameters.")?; 2735 2736 let km_uuid = Self::get_key_km_uuid(tx, key_id) 2737 .context("In load_key_components: Trying to get KM uuid.")?; 2738 2739 Ok(KeyEntry { 2740 id: key_id, 2741 key_blob_info, 2742 cert: cert_blob, 2743 cert_chain: cert_chain_blob, 2744 km_uuid, 2745 parameters, 2746 metadata, 2747 pure_cert: !has_km_blob, 2748 }) 2749 } 2750 2751 /// Returns a list of KeyDescriptors in the selected domain/namespace whose 2752 /// aliases are greater than the specified 'start_past_alias'. If no value 2753 /// is provided, returns all KeyDescriptors. 2754 /// The key descriptors will have the domain, nspace, and alias field set. 2755 /// The returned list will be sorted by alias. 2756 /// Domain must be APP or SELINUX, the caller must make sure of that. 2757 /// Number of returned values is limited to 10,000 (which is empirically roughly 2758 /// what will fit in a Binder message). list_past_alias( &mut self, domain: Domain, namespace: i64, key_type: KeyType, start_past_alias: Option<&str>, ) -> Result<Vec<KeyDescriptor>>2759 pub fn list_past_alias( 2760 &mut self, 2761 domain: Domain, 2762 namespace: i64, 2763 key_type: KeyType, 2764 start_past_alias: Option<&str>, 2765 ) -> Result<Vec<KeyDescriptor>> { 2766 let _wp = wd::watch("KeystoreDB::list_past_alias"); 2767 2768 let query = format!( 2769 "SELECT DISTINCT alias FROM persistent.keyentry 2770 WHERE domain = ? 2771 AND namespace = ? 2772 AND alias IS NOT NULL 2773 AND state = ? 2774 AND key_type = ? 2775 {} 2776 ORDER BY alias ASC 2777 LIMIT 10000;", 2778 if start_past_alias.is_some() { " AND alias > ?" } else { "" } 2779 ); 2780 2781 self.with_transaction(TransactionBehavior::Deferred, |tx| { 2782 let mut stmt = tx.prepare(&query).context(ks_err!("Failed to prepare."))?; 2783 2784 let mut rows = match start_past_alias { 2785 Some(past_alias) => stmt 2786 .query(params![ 2787 domain.0 as u32, 2788 namespace, 2789 KeyLifeCycle::Live, 2790 key_type, 2791 past_alias 2792 ]) 2793 .context(ks_err!("Failed to query."))?, 2794 None => stmt 2795 .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type,]) 2796 .context(ks_err!("Failed to query."))?, 2797 }; 2798 2799 let mut descriptors: Vec<KeyDescriptor> = Vec::new(); 2800 db_utils::with_rows_extract_all(&mut rows, |row| { 2801 descriptors.push(KeyDescriptor { 2802 domain, 2803 nspace: namespace, 2804 alias: Some(row.get(0).context("Trying to extract alias.")?), 2805 blob: None, 2806 }); 2807 Ok(()) 2808 }) 2809 .context(ks_err!("Failed to extract rows."))?; 2810 Ok(descriptors).no_gc() 2811 }) 2812 } 2813 2814 /// Returns a number of KeyDescriptors in the selected domain/namespace. 2815 /// Domain must be APP or SELINUX, the caller must make sure of that. count_keys( &mut self, domain: Domain, namespace: i64, key_type: KeyType, ) -> Result<usize>2816 pub fn count_keys( 2817 &mut self, 2818 domain: Domain, 2819 namespace: i64, 2820 key_type: KeyType, 2821 ) -> Result<usize> { 2822 let _wp = wd::watch("KeystoreDB::countKeys"); 2823 2824 let num_keys = self.with_transaction(TransactionBehavior::Deferred, |tx| { 2825 tx.query_row( 2826 "SELECT COUNT(alias) FROM persistent.keyentry 2827 WHERE domain = ? 2828 AND namespace = ? 2829 AND alias IS NOT NULL 2830 AND state = ? 2831 AND key_type = ?;", 2832 params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type], 2833 |row| row.get(0), 2834 ) 2835 .context(ks_err!("Failed to count number of keys.")) 2836 .no_gc() 2837 })?; 2838 Ok(num_keys) 2839 } 2840 2841 /// Adds a grant to the grant table. 2842 /// Like `load_key_entry` this function loads the access tuple before 2843 /// it uses the callback for a permission check. Upon success, 2844 /// it inserts the `grantee_uid`, `key_id`, and `access_vector` into the 2845 /// grant table. The new row will have a randomized id, which is used as 2846 /// 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>2847 pub fn grant( 2848 &mut self, 2849 key: &KeyDescriptor, 2850 caller_uid: u32, 2851 grantee_uid: u32, 2852 access_vector: KeyPermSet, 2853 check_permission: impl Fn(&KeyDescriptor, &KeyPermSet) -> Result<()>, 2854 ) -> Result<KeyDescriptor> { 2855 let _wp = wd::watch("KeystoreDB::grant"); 2856 2857 self.with_transaction(Immediate("TX_grant"), |tx| { 2858 // Load the key_id and complete the access control tuple. 2859 // We ignore the access vector here because grants cannot be granted. 2860 // The access vector returned here expresses the permissions the 2861 // grantee has if key.domain == Domain::GRANT. But this vector 2862 // cannot include the grant permission by design, so there is no way the 2863 // subsequent permission check can pass. 2864 // We could check key.domain == Domain::GRANT and fail early. 2865 // But even if we load the access tuple by grant here, the permission 2866 // check denies the attempt to create a grant by grant descriptor. 2867 let access = 2868 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid).context(ks_err!())?; 2869 2870 // Perform access control. It is vital that we return here if the permission 2871 // was denied. So do not touch that '?' at the end of the line. 2872 // This permission check checks if the caller has the grant permission 2873 // for the given key and in addition to all of the permissions 2874 // expressed in `access_vector`. 2875 check_permission(&access.descriptor, &access_vector) 2876 .context(ks_err!("check_permission failed"))?; 2877 2878 let grant_id = if let Some(grant_id) = tx 2879 .query_row( 2880 "SELECT id FROM persistent.grant 2881 WHERE keyentryid = ? AND grantee = ?;", 2882 params![access.key_id, grantee_uid], 2883 |row| row.get(0), 2884 ) 2885 .optional() 2886 .context(ks_err!("Failed get optional existing grant id."))? 2887 { 2888 tx.execute( 2889 "UPDATE persistent.grant 2890 SET access_vector = ? 2891 WHERE id = ?;", 2892 params![i32::from(access_vector), grant_id], 2893 ) 2894 .context(ks_err!("Failed to update existing grant."))?; 2895 grant_id 2896 } else { 2897 Self::insert_with_retry(|id| { 2898 tx.execute( 2899 "INSERT INTO persistent.grant (id, grantee, keyentryid, access_vector) 2900 VALUES (?, ?, ?, ?);", 2901 params![id, grantee_uid, access.key_id, i32::from(access_vector)], 2902 ) 2903 }) 2904 .context(ks_err!())? 2905 }; 2906 2907 Ok(KeyDescriptor { domain: Domain::GRANT, nspace: grant_id, alias: None, blob: None }) 2908 .no_gc() 2909 }) 2910 } 2911 2912 /// This function checks permissions like `grant` and `load_key_entry` 2913 /// 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<()>2914 pub fn ungrant( 2915 &mut self, 2916 key: &KeyDescriptor, 2917 caller_uid: u32, 2918 grantee_uid: u32, 2919 check_permission: impl Fn(&KeyDescriptor) -> Result<()>, 2920 ) -> Result<()> { 2921 let _wp = wd::watch("KeystoreDB::ungrant"); 2922 2923 self.with_transaction(Immediate("TX_ungrant"), |tx| { 2924 // Load the key_id and complete the access control tuple. 2925 // We ignore the access vector here because grants cannot be granted. 2926 let access = 2927 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid).context(ks_err!())?; 2928 2929 // Perform access control. We must return here if the permission 2930 // was denied. So do not touch the '?' at the end of this line. 2931 check_permission(&access.descriptor).context(ks_err!("check_permission failed."))?; 2932 2933 tx.execute( 2934 "DELETE FROM persistent.grant 2935 WHERE keyentryid = ? AND grantee = ?;", 2936 params![access.key_id, grantee_uid], 2937 ) 2938 .context("Failed to delete grant.")?; 2939 2940 Ok(()).no_gc() 2941 }) 2942 } 2943 2944 // Generates a random id and passes it to the given function, which will 2945 // try to insert it into a database. If that insertion fails, retry; 2946 // otherwise return the id. insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64>2947 fn insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64> { 2948 loop { 2949 let newid: i64 = match random() { 2950 Self::UNASSIGNED_KEY_ID => continue, // UNASSIGNED_KEY_ID cannot be assigned. 2951 i => i, 2952 }; 2953 match inserter(newid) { 2954 // If the id already existed, try again. 2955 Err(rusqlite::Error::SqliteFailure( 2956 libsqlite3_sys::Error { 2957 code: libsqlite3_sys::ErrorCode::ConstraintViolation, 2958 extended_code: libsqlite3_sys::SQLITE_CONSTRAINT_UNIQUE, 2959 }, 2960 _, 2961 )) => (), 2962 Err(e) => { 2963 return Err(e).context(ks_err!("failed to insert into database.")); 2964 } 2965 _ => return Ok(newid), 2966 } 2967 } 2968 } 2969 2970 /// Insert or replace the auth token based on (user_id, auth_id, auth_type) insert_auth_token(&mut self, auth_token: &HardwareAuthToken)2971 pub fn insert_auth_token(&mut self, auth_token: &HardwareAuthToken) { 2972 self.perboot 2973 .insert_auth_token_entry(AuthTokenEntry::new(auth_token.clone(), BootTime::now())) 2974 } 2975 2976 /// Find the newest auth token matching the given predicate. find_auth_token_entry<F>(&self, p: F) -> Option<AuthTokenEntry> where F: Fn(&AuthTokenEntry) -> bool,2977 pub fn find_auth_token_entry<F>(&self, p: F) -> Option<AuthTokenEntry> 2978 where 2979 F: Fn(&AuthTokenEntry) -> bool, 2980 { 2981 self.perboot.find_auth_token_entry(p) 2982 } 2983 2984 /// Load descriptor of a key by key id load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>>2985 pub fn load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>> { 2986 let _wp = wd::watch("KeystoreDB::load_key_descriptor"); 2987 2988 self.with_transaction(TransactionBehavior::Deferred, |tx| { 2989 tx.query_row( 2990 "SELECT domain, namespace, alias FROM persistent.keyentry WHERE id = ?;", 2991 params![key_id], 2992 |row| { 2993 Ok(KeyDescriptor { 2994 domain: Domain(row.get(0)?), 2995 nspace: row.get(1)?, 2996 alias: row.get(2)?, 2997 blob: None, 2998 }) 2999 }, 3000 ) 3001 .optional() 3002 .context("Trying to load key descriptor") 3003 .no_gc() 3004 }) 3005 .context(ks_err!()) 3006 } 3007 3008 /// Returns a list of app UIDs that have keys authenticated by the given secure_user_id 3009 /// (for the given user_id). 3010 /// This is helpful for finding out which apps will have their keys invalidated when 3011 /// the user changes biometrics enrollment or removes their LSKF. get_app_uids_affected_by_sid( &mut self, user_id: i32, secure_user_id: i64, ) -> Result<Vec<i64>>3012 pub fn get_app_uids_affected_by_sid( 3013 &mut self, 3014 user_id: i32, 3015 secure_user_id: i64, 3016 ) -> Result<Vec<i64>> { 3017 let _wp = wd::watch("KeystoreDB::get_app_uids_affected_by_sid"); 3018 3019 let ids = self.with_transaction(Immediate("TX_get_app_uids_affected_by_sid"), |tx| { 3020 let mut stmt = tx 3021 .prepare(&format!( 3022 "SELECT id, namespace from persistent.keyentry 3023 WHERE key_type = ? 3024 AND domain = ? 3025 AND cast ( (namespace/{AID_USER_OFFSET}) as int) = ? 3026 AND state = ?;", 3027 )) 3028 .context(concat!( 3029 "In get_app_uids_affected_by_sid, ", 3030 "failed to prepare the query to find the keys created by apps." 3031 ))?; 3032 3033 let mut rows = stmt 3034 .query(params![KeyType::Client, Domain::APP.0 as u32, user_id, KeyLifeCycle::Live,]) 3035 .context(ks_err!("Failed to query the keys created by apps."))?; 3036 3037 let mut key_ids_and_app_uids: HashMap<i64, i64> = Default::default(); 3038 db_utils::with_rows_extract_all(&mut rows, |row| { 3039 key_ids_and_app_uids.insert( 3040 row.get(0).context("Failed to read key id of a key created by an app.")?, 3041 row.get(1).context("Failed to read the app uid")?, 3042 ); 3043 Ok(()) 3044 })?; 3045 Ok(key_ids_and_app_uids).no_gc() 3046 })?; 3047 let mut app_uids_affected_by_sid: HashSet<i64> = Default::default(); 3048 for (key_id, app_uid) in ids { 3049 // Read the key parameters for each key in its own transaction. It is OK to ignore 3050 // an error to get the properties of a particular key since it might have been deleted 3051 // under our feet after the previous transaction concluded. If the key was deleted 3052 // then it is no longer applicable if it was auth-bound or not. 3053 if let Ok(is_key_bound_to_sid) = 3054 self.with_transaction(Immediate("TX_get_app_uids_affects_by_sid 2"), |tx| { 3055 let params = Self::load_key_parameters(key_id, tx) 3056 .context("Failed to load key parameters.")?; 3057 // Check if the key is bound to this secure user ID. 3058 let is_key_bound_to_sid = params.iter().any(|kp| { 3059 matches!( 3060 kp.key_parameter_value(), 3061 KeyParameterValue::UserSecureID(sid) if *sid == secure_user_id 3062 ) 3063 }); 3064 Ok(is_key_bound_to_sid).no_gc() 3065 }) 3066 { 3067 if is_key_bound_to_sid { 3068 app_uids_affected_by_sid.insert(app_uid); 3069 } 3070 } 3071 } 3072 3073 let app_uids_vec: Vec<i64> = app_uids_affected_by_sid.into_iter().collect(); 3074 Ok(app_uids_vec) 3075 } 3076 3077 /// Retrieve a database PRAGMA config value. pragma<T: FromSql>(&mut self, name: &str) -> Result<T>3078 pub fn pragma<T: FromSql>(&mut self, name: &str) -> Result<T> { 3079 self.conn 3080 .query_row(&format!("PRAGMA persistent.{name}"), (), |row| row.get(0)) 3081 .context(format!("failed to read pragma {name}")) 3082 } 3083 } 3084