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 // Connect to database in specific mode 1167 let persistent_path_mode = if keystore2_flags::wal_db_journalmode_v3() { 1168 "?journal_mode=WAL".to_owned() 1169 } else { 1170 "?journal_mode=DELETE".to_owned() 1171 }; 1172 persistent_path_str.push_str(&persistent_path_mode); 1173 1174 Ok(persistent_path_str) 1175 } 1176 make_connection(persistent_file: &str) -> Result<Connection>1177 fn make_connection(persistent_file: &str) -> Result<Connection> { 1178 let conn = 1179 Connection::open_in_memory().context("Failed to initialize SQLite connection.")?; 1180 1181 loop { 1182 if let Err(e) = conn 1183 .execute("ATTACH DATABASE ? as persistent;", params![persistent_file]) 1184 .context("Failed to attach database persistent.") 1185 { 1186 if Self::is_locked_error(&e) { 1187 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 1188 continue; 1189 } else { 1190 return Err(e); 1191 } 1192 } 1193 break; 1194 } 1195 1196 // Drop the cache size from default (2M) to 0.5M 1197 conn.execute("PRAGMA persistent.cache_size = -500;", params![]) 1198 .context("Failed to decrease cache size for persistent db")?; 1199 1200 Ok(conn) 1201 } 1202 do_table_size_query( &mut self, storage_type: MetricsStorage, query: &str, params: &[&str], ) -> Result<StorageStats>1203 fn do_table_size_query( 1204 &mut self, 1205 storage_type: MetricsStorage, 1206 query: &str, 1207 params: &[&str], 1208 ) -> Result<StorageStats> { 1209 let (total, unused) = self.with_transaction(TransactionBehavior::Deferred, |tx| { 1210 tx.query_row(query, params_from_iter(params), |row| Ok((row.get(0)?, row.get(1)?))) 1211 .with_context(|| { 1212 ks_err!("get_storage_stat: Error size of storage type {}", storage_type.0) 1213 }) 1214 .no_gc() 1215 })?; 1216 Ok(StorageStats { storage_type, size: total, unused_size: unused }) 1217 } 1218 get_total_size(&mut self) -> Result<StorageStats>1219 fn get_total_size(&mut self) -> Result<StorageStats> { 1220 self.do_table_size_query( 1221 MetricsStorage::DATABASE, 1222 "SELECT page_count * page_size, freelist_count * page_size 1223 FROM pragma_page_count('persistent'), 1224 pragma_page_size('persistent'), 1225 persistent.pragma_freelist_count();", 1226 &[], 1227 ) 1228 } 1229 get_table_size( &mut self, storage_type: MetricsStorage, schema: &str, table: &str, ) -> Result<StorageStats>1230 fn get_table_size( 1231 &mut self, 1232 storage_type: MetricsStorage, 1233 schema: &str, 1234 table: &str, 1235 ) -> Result<StorageStats> { 1236 self.do_table_size_query( 1237 storage_type, 1238 "SELECT pgsize,unused FROM dbstat(?1) 1239 WHERE name=?2 AND aggregate=TRUE;", 1240 &[schema, table], 1241 ) 1242 } 1243 1244 /// Fetches a storage statistics atom for a given storage type. For storage 1245 /// types that map to a table, information about the table's storage is 1246 /// returned. Requests for storage types that are not DB tables return None. get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats>1247 pub fn get_storage_stat(&mut self, storage_type: MetricsStorage) -> Result<StorageStats> { 1248 let _wp = wd::watch_millis_with("KeystoreDB::get_storage_stat", 500, storage_type); 1249 1250 match storage_type { 1251 MetricsStorage::DATABASE => self.get_total_size(), 1252 MetricsStorage::KEY_ENTRY => { 1253 self.get_table_size(storage_type, "persistent", "keyentry") 1254 } 1255 MetricsStorage::KEY_ENTRY_ID_INDEX => { 1256 self.get_table_size(storage_type, "persistent", "keyentry_id_index") 1257 } 1258 MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX => { 1259 self.get_table_size(storage_type, "persistent", "keyentry_domain_namespace_index") 1260 } 1261 MetricsStorage::BLOB_ENTRY => { 1262 self.get_table_size(storage_type, "persistent", "blobentry") 1263 } 1264 MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX => { 1265 self.get_table_size(storage_type, "persistent", "blobentry_keyentryid_index") 1266 } 1267 MetricsStorage::KEY_PARAMETER => { 1268 self.get_table_size(storage_type, "persistent", "keyparameter") 1269 } 1270 MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX => { 1271 self.get_table_size(storage_type, "persistent", "keyparameter_keyentryid_index") 1272 } 1273 MetricsStorage::KEY_METADATA => { 1274 self.get_table_size(storage_type, "persistent", "keymetadata") 1275 } 1276 MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX => { 1277 self.get_table_size(storage_type, "persistent", "keymetadata_keyentryid_index") 1278 } 1279 MetricsStorage::GRANT => self.get_table_size(storage_type, "persistent", "grant"), 1280 MetricsStorage::AUTH_TOKEN => { 1281 // Since the table is actually a BTreeMap now, unused_size is not meaningfully 1282 // reportable 1283 // Size provided is only an approximation 1284 Ok(StorageStats { 1285 storage_type, 1286 size: (self.perboot.auth_tokens_len() * std::mem::size_of::<AuthTokenEntry>()) 1287 as i32, 1288 unused_size: 0, 1289 }) 1290 } 1291 MetricsStorage::BLOB_METADATA => { 1292 self.get_table_size(storage_type, "persistent", "blobmetadata") 1293 } 1294 MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX => { 1295 self.get_table_size(storage_type, "persistent", "blobmetadata_blobentryid_index") 1296 } 1297 _ => Err(anyhow::Error::msg(format!("Unsupported storage type: {}", storage_type.0))), 1298 } 1299 } 1300 1301 /// This function is intended to be used by the garbage collector. 1302 /// It deletes the blobs given by `blob_ids_to_delete`. It then tries to find up to `max_blobs` 1303 /// superseded key blobs that might need special handling by the garbage collector. 1304 /// If no further superseded blobs can be found it deletes all other superseded blobs that don't 1305 /// need special handling and returns None. handle_next_superseded_blobs( &mut self, blob_ids_to_delete: &[i64], max_blobs: usize, ) -> Result<Vec<SupersededBlob>>1306 pub fn handle_next_superseded_blobs( 1307 &mut self, 1308 blob_ids_to_delete: &[i64], 1309 max_blobs: usize, 1310 ) -> Result<Vec<SupersededBlob>> { 1311 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob"); 1312 self.with_transaction(Immediate("TX_handle_next_superseded_blob"), |tx| { 1313 // Delete the given blobs. 1314 for blob_id in blob_ids_to_delete { 1315 tx.execute( 1316 "DELETE FROM persistent.blobmetadata WHERE blobentryid = ?;", 1317 params![blob_id], 1318 ) 1319 .context(ks_err!("Trying to delete blob metadata: {:?}", blob_id))?; 1320 tx.execute("DELETE FROM persistent.blobentry WHERE id = ?;", params![blob_id]) 1321 .context(ks_err!("Trying to delete blob: {:?}", blob_id))?; 1322 } 1323 1324 Self::cleanup_unreferenced(tx).context("Trying to cleanup unreferenced.")?; 1325 1326 // Find up to `max_blobs` more out-of-date key blobs, load their metadata and return it. 1327 let result: Vec<(i64, Vec<u8>)> = if keystore2_flags::use_blob_state_column() { 1328 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob find_next v2"); 1329 let mut stmt = tx 1330 .prepare( 1331 "SELECT id, blob FROM persistent.blobentry 1332 WHERE subcomponent_type = ? AND state != ? 1333 LIMIT ?;", 1334 ) 1335 .context("Trying to prepare query for superseded blobs.")?; 1336 1337 let rows = stmt 1338 .query_map( 1339 params![SubComponentType::KEY_BLOB, BlobState::Current, max_blobs as i64], 1340 |row| Ok((row.get(0)?, row.get(1)?)), 1341 ) 1342 .context("Trying to query superseded blob.")?; 1343 1344 rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>() 1345 .context("Trying to extract superseded blobs.")? 1346 } else { 1347 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob find_next v1"); 1348 let mut stmt = tx 1349 .prepare( 1350 "SELECT id, blob FROM persistent.blobentry 1351 WHERE subcomponent_type = ? 1352 AND ( 1353 id NOT IN ( 1354 SELECT MAX(id) FROM persistent.blobentry 1355 WHERE subcomponent_type = ? 1356 GROUP BY keyentryid, subcomponent_type 1357 ) 1358 OR keyentryid NOT IN (SELECT id FROM persistent.keyentry) 1359 ) LIMIT ?;", 1360 ) 1361 .context("Trying to prepare query for superseded blobs.")?; 1362 1363 let rows = stmt 1364 .query_map( 1365 params![ 1366 SubComponentType::KEY_BLOB, 1367 SubComponentType::KEY_BLOB, 1368 max_blobs as i64, 1369 ], 1370 |row| Ok((row.get(0)?, row.get(1)?)), 1371 ) 1372 .context("Trying to query superseded blob.")?; 1373 1374 rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>() 1375 .context("Trying to extract superseded blobs.")? 1376 }; 1377 1378 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob load_metadata"); 1379 let result = result 1380 .into_iter() 1381 .map(|(blob_id, blob)| { 1382 Ok(SupersededBlob { 1383 blob_id, 1384 blob, 1385 metadata: BlobMetaData::load_from_db(blob_id, tx)?, 1386 }) 1387 }) 1388 .collect::<Result<Vec<_>>>() 1389 .context("Trying to load blob metadata.")?; 1390 if !result.is_empty() { 1391 return Ok(result).no_gc(); 1392 } 1393 1394 // We did not find any out-of-date key blobs, so let's remove other types of superseded 1395 // blob in one transaction. 1396 if keystore2_flags::use_blob_state_column() { 1397 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob delete v2"); 1398 tx.execute( 1399 "DELETE FROM persistent.blobentry 1400 WHERE subcomponent_type != ? AND state != ?;", 1401 params![SubComponentType::KEY_BLOB, BlobState::Current], 1402 ) 1403 .context("Trying to purge out-of-date blobs (other than keyblobs)")?; 1404 } else { 1405 let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob delete v1"); 1406 tx.execute( 1407 "DELETE FROM persistent.blobentry 1408 WHERE NOT subcomponent_type = ? 1409 AND ( 1410 id NOT IN ( 1411 SELECT MAX(id) FROM persistent.blobentry 1412 WHERE NOT subcomponent_type = ? 1413 GROUP BY keyentryid, subcomponent_type 1414 ) OR keyentryid NOT IN (SELECT id FROM persistent.keyentry) 1415 );", 1416 params![SubComponentType::KEY_BLOB, SubComponentType::KEY_BLOB], 1417 ) 1418 .context("Trying to purge superseded blobs.")?; 1419 } 1420 1421 Ok(vec![]).no_gc() 1422 }) 1423 .context(ks_err!()) 1424 } 1425 1426 /// This maintenance function should be called only once before the database is used for the 1427 /// first time. It restores the invariant that `KeyLifeCycle::Existing` is a transient state. 1428 /// The function transitions all key entries from Existing to Unreferenced unconditionally and 1429 /// returns the number of rows affected. If this returns a value greater than 0, it means that 1430 /// Keystore crashed at some point during key generation. Callers may want to log such 1431 /// occurrences. 1432 /// Unlike with `mark_unreferenced`, we don't need to purge grants, because only keys that made 1433 /// it to `KeyLifeCycle::Live` may have grants. cleanup_leftovers(&mut self) -> Result<usize>1434 pub fn cleanup_leftovers(&mut self) -> Result<usize> { 1435 let _wp = wd::watch("KeystoreDB::cleanup_leftovers"); 1436 1437 self.with_transaction(Immediate("TX_cleanup_leftovers"), |tx| { 1438 tx.execute( 1439 "UPDATE persistent.keyentry SET state = ? WHERE state = ?;", 1440 params![KeyLifeCycle::Unreferenced, KeyLifeCycle::Existing], 1441 ) 1442 .context("Failed to execute query.") 1443 .need_gc() 1444 }) 1445 .context(ks_err!()) 1446 } 1447 1448 /// 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>1449 pub fn key_exists( 1450 &mut self, 1451 domain: Domain, 1452 nspace: i64, 1453 alias: &str, 1454 key_type: KeyType, 1455 ) -> Result<bool> { 1456 let _wp = wd::watch("KeystoreDB::key_exists"); 1457 1458 self.with_transaction(Immediate("TX_key_exists"), |tx| { 1459 let key_descriptor = 1460 KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None }; 1461 let result = Self::load_key_entry_id(tx, &key_descriptor, key_type); 1462 match result { 1463 Ok(_) => Ok(true), 1464 Err(error) => match error.root_cause().downcast_ref::<KsError>() { 1465 Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(false), 1466 _ => Err(error).context(ks_err!("Failed to find if the key exists.")), 1467 }, 1468 } 1469 .no_gc() 1470 }) 1471 .context(ks_err!()) 1472 } 1473 1474 /// 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>1475 pub fn store_super_key( 1476 &mut self, 1477 user_id: u32, 1478 key_type: &SuperKeyType, 1479 blob: &[u8], 1480 blob_metadata: &BlobMetaData, 1481 key_metadata: &KeyMetaData, 1482 ) -> Result<KeyEntry> { 1483 let _wp = wd::watch("KeystoreDB::store_super_key"); 1484 1485 self.with_transaction(Immediate("TX_store_super_key"), |tx| { 1486 let key_id = Self::insert_with_retry(|id| { 1487 tx.execute( 1488 "INSERT into persistent.keyentry 1489 (id, key_type, domain, namespace, alias, state, km_uuid) 1490 VALUES(?, ?, ?, ?, ?, ?, ?);", 1491 params![ 1492 id, 1493 KeyType::Super, 1494 Domain::APP.0, 1495 user_id as i64, 1496 key_type.alias, 1497 KeyLifeCycle::Live, 1498 &KEYSTORE_UUID, 1499 ], 1500 ) 1501 }) 1502 .context("Failed to insert into keyentry table.")?; 1503 1504 key_metadata.store_in_db(key_id, tx).context("KeyMetaData::store_in_db failed")?; 1505 1506 Self::set_blob_internal( 1507 tx, 1508 key_id, 1509 SubComponentType::KEY_BLOB, 1510 Some(blob), 1511 Some(blob_metadata), 1512 ) 1513 .context("Failed to store key blob.")?; 1514 1515 Self::load_key_components(tx, KeyEntryLoadBits::KM, key_id) 1516 .context("Trying to load key components.") 1517 .no_gc() 1518 }) 1519 .context(ks_err!()) 1520 } 1521 1522 /// Loads super key of a given user, if exists load_super_key( &mut self, key_type: &SuperKeyType, user_id: u32, ) -> Result<Option<(KeyIdGuard, KeyEntry)>>1523 pub fn load_super_key( 1524 &mut self, 1525 key_type: &SuperKeyType, 1526 user_id: u32, 1527 ) -> Result<Option<(KeyIdGuard, KeyEntry)>> { 1528 let _wp = wd::watch("KeystoreDB::load_super_key"); 1529 1530 self.with_transaction(Immediate("TX_load_super_key"), |tx| { 1531 let key_descriptor = KeyDescriptor { 1532 domain: Domain::APP, 1533 nspace: user_id as i64, 1534 alias: Some(key_type.alias.into()), 1535 blob: None, 1536 }; 1537 let id = Self::load_key_entry_id(tx, &key_descriptor, KeyType::Super); 1538 match id { 1539 Ok(id) => { 1540 let key_entry = Self::load_key_components(tx, KeyEntryLoadBits::KM, id) 1541 .context(ks_err!("Failed to load key entry."))?; 1542 Ok(Some((KEY_ID_LOCK.get(id), key_entry))) 1543 } 1544 Err(error) => match error.root_cause().downcast_ref::<KsError>() { 1545 Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None), 1546 _ => Err(error).context(ks_err!()), 1547 }, 1548 } 1549 .no_gc() 1550 }) 1551 .context(ks_err!()) 1552 } 1553 1554 /// Creates a transaction with the given behavior and executes f with the new transaction. 1555 /// The transaction is committed only if f returns Ok and retried if DatabaseBusy 1556 /// or DatabaseLocked is encountered. with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T> where F: Fn(&Transaction) -> Result<(bool, T)>,1557 fn with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T> 1558 where 1559 F: Fn(&Transaction) -> Result<(bool, T)>, 1560 { 1561 let name = behavior.name(); 1562 loop { 1563 let result = self 1564 .conn 1565 .transaction_with_behavior(behavior.into()) 1566 .context(ks_err!()) 1567 .and_then(|tx| { 1568 let _wp = name.map(wd::watch); 1569 f(&tx).map(|result| (result, tx)) 1570 }) 1571 .and_then(|(result, tx)| { 1572 tx.commit().context(ks_err!("Failed to commit transaction."))?; 1573 Ok(result) 1574 }); 1575 match result { 1576 Ok(result) => break Ok(result), 1577 Err(e) => { 1578 if Self::is_locked_error(&e) { 1579 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 1580 continue; 1581 } else { 1582 return Err(e).context(ks_err!()); 1583 } 1584 } 1585 } 1586 } 1587 .map(|(need_gc, result)| { 1588 if need_gc { 1589 if let Some(ref gc) = self.gc { 1590 gc.notify_gc(); 1591 } 1592 } 1593 result 1594 }) 1595 } 1596 is_locked_error(e: &anyhow::Error) -> bool1597 fn is_locked_error(e: &anyhow::Error) -> bool { 1598 matches!( 1599 e.root_cause().downcast_ref::<rusqlite::ffi::Error>(), 1600 Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) 1601 | Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseLocked, .. }) 1602 ) 1603 } 1604 create_key_entry_internal( tx: &Transaction, domain: &Domain, namespace: &i64, key_type: KeyType, km_uuid: &Uuid, ) -> Result<KeyIdGuard>1605 fn create_key_entry_internal( 1606 tx: &Transaction, 1607 domain: &Domain, 1608 namespace: &i64, 1609 key_type: KeyType, 1610 km_uuid: &Uuid, 1611 ) -> Result<KeyIdGuard> { 1612 match *domain { 1613 Domain::APP | Domain::SELINUX => {} 1614 _ => { 1615 return Err(KsError::sys()) 1616 .context(ks_err!("Domain {:?} must be either App or SELinux.", domain)); 1617 } 1618 } 1619 Ok(KEY_ID_LOCK.get( 1620 Self::insert_with_retry(|id| { 1621 tx.execute( 1622 "INSERT into persistent.keyentry 1623 (id, key_type, domain, namespace, alias, state, km_uuid) 1624 VALUES(?, ?, ?, ?, NULL, ?, ?);", 1625 params![ 1626 id, 1627 key_type, 1628 domain.0 as u32, 1629 *namespace, 1630 KeyLifeCycle::Existing, 1631 km_uuid, 1632 ], 1633 ) 1634 }) 1635 .context(ks_err!())?, 1636 )) 1637 } 1638 1639 /// Set a new blob and associates it with the given key id. Each blob 1640 /// has a sub component type. 1641 /// Each key can have one of each sub component type associated. If more 1642 /// are added only the most recent can be retrieved, and superseded blobs 1643 /// will get garbage collected. 1644 /// Components SubComponentType::CERT and SubComponentType::CERT_CHAIN can be 1645 /// removed by setting blob to None. set_blob( &mut self, key_id: &KeyIdGuard, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1646 pub fn set_blob( 1647 &mut self, 1648 key_id: &KeyIdGuard, 1649 sc_type: SubComponentType, 1650 blob: Option<&[u8]>, 1651 blob_metadata: Option<&BlobMetaData>, 1652 ) -> Result<()> { 1653 let _wp = wd::watch("KeystoreDB::set_blob"); 1654 1655 self.with_transaction(Immediate("TX_set_blob"), |tx| { 1656 Self::set_blob_internal(tx, key_id.0, sc_type, blob, blob_metadata).need_gc() 1657 }) 1658 .context(ks_err!()) 1659 } 1660 1661 /// Why would we insert a deleted blob? This weird function is for the purpose of legacy 1662 /// key migration in the case where we bulk delete all the keys of an app or even a user. 1663 /// We use this to insert key blobs into the database which can then be garbage collected 1664 /// lazily by the key garbage collector. set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()>1665 pub fn set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()> { 1666 let _wp = wd::watch("KeystoreDB::set_deleted_blob"); 1667 1668 self.with_transaction(Immediate("TX_set_deleted_blob"), |tx| { 1669 Self::set_blob_internal( 1670 tx, 1671 Self::UNASSIGNED_KEY_ID, 1672 SubComponentType::KEY_BLOB, 1673 Some(blob), 1674 Some(blob_metadata), 1675 ) 1676 .need_gc() 1677 }) 1678 .context(ks_err!()) 1679 } 1680 set_blob_internal( tx: &Transaction, key_id: i64, sc_type: SubComponentType, blob: Option<&[u8]>, blob_metadata: Option<&BlobMetaData>, ) -> Result<()>1681 fn set_blob_internal( 1682 tx: &Transaction, 1683 key_id: i64, 1684 sc_type: SubComponentType, 1685 blob: Option<&[u8]>, 1686 blob_metadata: Option<&BlobMetaData>, 1687 ) -> Result<()> { 1688 match (blob, sc_type) { 1689 (Some(blob), _) => { 1690 // Mark any previous blobentry(s) of the same type for the same key as superseded. 1691 tx.execute( 1692 "UPDATE persistent.blobentry SET state = ? 1693 WHERE keyentryid = ? AND subcomponent_type = ?", 1694 params![BlobState::Superseded, key_id, sc_type], 1695 ) 1696 .context(ks_err!( 1697 "Failed to mark prior {sc_type:?} blobentrys for {key_id} as superseded" 1698 ))?; 1699 1700 // Now insert the new, un-superseded, blob. (If this fails, the marking of 1701 // old blobs as superseded will be rolled back, because we're inside a 1702 // transaction.) 1703 tx.execute( 1704 "INSERT INTO persistent.blobentry 1705 (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);", 1706 params![sc_type, key_id, blob], 1707 ) 1708 .context(ks_err!("Failed to insert blob."))?; 1709 1710 if let Some(blob_metadata) = blob_metadata { 1711 let blob_id = tx 1712 .query_row("SELECT MAX(id) FROM persistent.blobentry;", [], |row| { 1713 row.get(0) 1714 }) 1715 .context(ks_err!("Failed to get new blob id."))?; 1716 1717 blob_metadata 1718 .store_in_db(blob_id, tx) 1719 .context(ks_err!("Trying to store blob metadata."))?; 1720 } 1721 } 1722 (None, SubComponentType::CERT) | (None, SubComponentType::CERT_CHAIN) => { 1723 tx.execute( 1724 "DELETE FROM persistent.blobentry 1725 WHERE subcomponent_type = ? AND keyentryid = ?;", 1726 params![sc_type, key_id], 1727 ) 1728 .context(ks_err!("Failed to delete blob."))?; 1729 } 1730 (None, _) => { 1731 return Err(KsError::sys()) 1732 .context(ks_err!("Other blobs cannot be deleted in this way.")); 1733 } 1734 } 1735 Ok(()) 1736 } 1737 1738 /// Inserts a collection of key parameters into the `persistent.keyparameter` table 1739 /// and associates them with the given `key_id`. 1740 #[cfg(test)] insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()>1741 fn insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()> { 1742 self.with_transaction(Immediate("TX_insert_keyparameter"), |tx| { 1743 Self::insert_keyparameter_internal(tx, key_id, params).no_gc() 1744 }) 1745 .context(ks_err!()) 1746 } 1747 insert_keyparameter_internal( tx: &Transaction, key_id: &KeyIdGuard, params: &[KeyParameter], ) -> Result<()>1748 fn insert_keyparameter_internal( 1749 tx: &Transaction, 1750 key_id: &KeyIdGuard, 1751 params: &[KeyParameter], 1752 ) -> Result<()> { 1753 let mut stmt = tx 1754 .prepare( 1755 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level) 1756 VALUES (?, ?, ?, ?);", 1757 ) 1758 .context(ks_err!("Failed to prepare statement."))?; 1759 1760 for p in params.iter() { 1761 stmt.insert(params![ 1762 key_id.0, 1763 p.get_tag().0, 1764 p.key_parameter_value(), 1765 p.security_level().0 1766 ]) 1767 .with_context(|| ks_err!("Failed to insert {:?}", p))?; 1768 } 1769 Ok(()) 1770 } 1771 1772 /// Insert a set of key entry specific metadata into the database. 1773 #[cfg(test)] insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()>1774 fn insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()> { 1775 self.with_transaction(Immediate("TX_insert_key_metadata"), |tx| { 1776 metadata.store_in_db(key_id.0, tx).no_gc() 1777 }) 1778 .context(ks_err!()) 1779 } 1780 1781 /// Updates the alias column of the given key id `newid` with the given alias, 1782 /// and atomically, removes the alias, domain, and namespace from another row 1783 /// with the same alias-domain-namespace tuple if such row exits. 1784 /// Returns Ok(true) if an old key was marked unreferenced as a hint to the garbage 1785 /// collector. rebind_alias( tx: &Transaction, newid: &KeyIdGuard, alias: &str, domain: &Domain, namespace: &i64, key_type: KeyType, ) -> Result<bool>1786 fn rebind_alias( 1787 tx: &Transaction, 1788 newid: &KeyIdGuard, 1789 alias: &str, 1790 domain: &Domain, 1791 namespace: &i64, 1792 key_type: KeyType, 1793 ) -> Result<bool> { 1794 match *domain { 1795 Domain::APP | Domain::SELINUX => {} 1796 _ => { 1797 return Err(KsError::sys()) 1798 .context(ks_err!("Domain {:?} must be either App or SELinux.", domain)); 1799 } 1800 } 1801 let updated = tx 1802 .execute( 1803 "UPDATE persistent.keyentry 1804 SET alias = NULL, domain = NULL, namespace = NULL, state = ? 1805 WHERE alias = ? AND domain = ? AND namespace = ? AND key_type = ?;", 1806 params![KeyLifeCycle::Unreferenced, alias, domain.0 as u32, namespace, key_type], 1807 ) 1808 .context(ks_err!("Failed to rebind existing entry."))?; 1809 let result = tx 1810 .execute( 1811 "UPDATE persistent.keyentry 1812 SET alias = ?, state = ? 1813 WHERE id = ? AND domain = ? AND namespace = ? AND state = ? AND key_type = ?;", 1814 params![ 1815 alias, 1816 KeyLifeCycle::Live, 1817 newid.0, 1818 domain.0 as u32, 1819 *namespace, 1820 KeyLifeCycle::Existing, 1821 key_type, 1822 ], 1823 ) 1824 .context(ks_err!("Failed to set alias."))?; 1825 if result != 1 { 1826 return Err(KsError::sys()).context(ks_err!( 1827 "Expected to update a single entry but instead updated {}.", 1828 result 1829 )); 1830 } 1831 Ok(updated != 0) 1832 } 1833 1834 /// Moves the key given by KeyIdGuard to the new location at `destination`. If the destination 1835 /// 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<()>1836 pub fn migrate_key_namespace( 1837 &mut self, 1838 key_id_guard: KeyIdGuard, 1839 destination: &KeyDescriptor, 1840 caller_uid: u32, 1841 check_permission: impl Fn(&KeyDescriptor) -> Result<()>, 1842 ) -> Result<()> { 1843 let _wp = wd::watch("KeystoreDB::migrate_key_namespace"); 1844 1845 let destination = match destination.domain { 1846 Domain::APP => KeyDescriptor { nspace: caller_uid as i64, ..(*destination).clone() }, 1847 Domain::SELINUX => (*destination).clone(), 1848 domain => { 1849 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1850 .context(format!("Domain {:?} must be either APP or SELINUX.", domain)); 1851 } 1852 }; 1853 1854 // Security critical: Must return immediately on failure. Do not remove the '?'; 1855 check_permission(&destination).context(ks_err!("Trying to check permission."))?; 1856 1857 let alias = destination 1858 .alias 1859 .as_ref() 1860 .ok_or(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1861 .context(ks_err!("Alias must be specified."))?; 1862 1863 self.with_transaction(Immediate("TX_migrate_key_namespace"), |tx| { 1864 // Query the destination location. If there is a key, the migration request fails. 1865 if tx 1866 .query_row( 1867 "SELECT id FROM persistent.keyentry 1868 WHERE alias = ? AND domain = ? AND namespace = ?;", 1869 params![alias, destination.domain.0, destination.nspace], 1870 |_| Ok(()), 1871 ) 1872 .optional() 1873 .context("Failed to query destination.")? 1874 .is_some() 1875 { 1876 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1877 .context("Target already exists."); 1878 } 1879 1880 let updated = tx 1881 .execute( 1882 "UPDATE persistent.keyentry 1883 SET alias = ?, domain = ?, namespace = ? 1884 WHERE id = ?;", 1885 params![alias, destination.domain.0, destination.nspace, key_id_guard.id()], 1886 ) 1887 .context("Failed to update key entry.")?; 1888 1889 if updated != 1 { 1890 return Err(KsError::sys()) 1891 .context(format!("Update succeeded, but {} rows were updated.", updated)); 1892 } 1893 Ok(()).no_gc() 1894 }) 1895 .context(ks_err!()) 1896 } 1897 1898 /// Store a new key in a single transaction. 1899 /// The function creates a new key entry, populates the blob, key parameter, and metadata 1900 /// fields, and rebinds the given alias to the new key. 1901 /// The boolean returned is a hint for the garbage collector. If true, a key was replaced, 1902 /// is now unreferenced and needs to be collected. 1903 #[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>1904 pub fn store_new_key( 1905 &mut self, 1906 key: &KeyDescriptor, 1907 key_type: KeyType, 1908 params: &[KeyParameter], 1909 blob_info: &BlobInfo, 1910 cert_info: &CertificateInfo, 1911 metadata: &KeyMetaData, 1912 km_uuid: &Uuid, 1913 ) -> Result<KeyIdGuard> { 1914 let _wp = wd::watch("KeystoreDB::store_new_key"); 1915 1916 let (alias, domain, namespace) = match key { 1917 KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None } 1918 | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => { 1919 (alias, key.domain, nspace) 1920 } 1921 _ => { 1922 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 1923 .context(ks_err!("Need alias and domain must be APP or SELINUX.")); 1924 } 1925 }; 1926 self.with_transaction(Immediate("TX_store_new_key"), |tx| { 1927 let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid) 1928 .context("Trying to create new key entry.")?; 1929 let BlobInfo { blob, metadata: blob_metadata, superseded_blob } = *blob_info; 1930 1931 // In some occasions the key blob is already upgraded during the import. 1932 // In order to make sure it gets properly deleted it is inserted into the 1933 // database here and then immediately replaced by the superseding blob. 1934 // The garbage collector will then subject the blob to deleteKey of the 1935 // KM back end to permanently invalidate the key. 1936 let need_gc = if let Some((blob, blob_metadata)) = superseded_blob { 1937 Self::set_blob_internal( 1938 tx, 1939 key_id.id(), 1940 SubComponentType::KEY_BLOB, 1941 Some(blob), 1942 Some(blob_metadata), 1943 ) 1944 .context("Trying to insert superseded key blob.")?; 1945 true 1946 } else { 1947 false 1948 }; 1949 1950 Self::set_blob_internal( 1951 tx, 1952 key_id.id(), 1953 SubComponentType::KEY_BLOB, 1954 Some(blob), 1955 Some(blob_metadata), 1956 ) 1957 .context("Trying to insert the key blob.")?; 1958 if let Some(cert) = &cert_info.cert { 1959 Self::set_blob_internal(tx, key_id.id(), SubComponentType::CERT, Some(cert), None) 1960 .context("Trying to insert the certificate.")?; 1961 } 1962 if let Some(cert_chain) = &cert_info.cert_chain { 1963 Self::set_blob_internal( 1964 tx, 1965 key_id.id(), 1966 SubComponentType::CERT_CHAIN, 1967 Some(cert_chain), 1968 None, 1969 ) 1970 .context("Trying to insert the certificate chain.")?; 1971 } 1972 Self::insert_keyparameter_internal(tx, &key_id, params) 1973 .context("Trying to insert key parameters.")?; 1974 metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?; 1975 let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type) 1976 .context("Trying to rebind alias.")? 1977 || need_gc; 1978 Ok(key_id).do_gc(need_gc) 1979 }) 1980 .context(ks_err!()) 1981 } 1982 1983 /// Store a new certificate 1984 /// The function creates a new key entry, populates the blob field and metadata, and rebinds 1985 /// the given alias to the new cert. store_new_certificate( &mut self, key: &KeyDescriptor, key_type: KeyType, cert: &[u8], km_uuid: &Uuid, ) -> Result<KeyIdGuard>1986 pub fn store_new_certificate( 1987 &mut self, 1988 key: &KeyDescriptor, 1989 key_type: KeyType, 1990 cert: &[u8], 1991 km_uuid: &Uuid, 1992 ) -> Result<KeyIdGuard> { 1993 let _wp = wd::watch("KeystoreDB::store_new_certificate"); 1994 1995 let (alias, domain, namespace) = match key { 1996 KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None } 1997 | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => { 1998 (alias, key.domain, nspace) 1999 } 2000 _ => { 2001 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)) 2002 .context(ks_err!("Need alias and domain must be APP or SELINUX.")); 2003 } 2004 }; 2005 self.with_transaction(Immediate("TX_store_new_certificate"), |tx| { 2006 let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid) 2007 .context("Trying to create new key entry.")?; 2008 2009 Self::set_blob_internal( 2010 tx, 2011 key_id.id(), 2012 SubComponentType::CERT_CHAIN, 2013 Some(cert), 2014 None, 2015 ) 2016 .context("Trying to insert certificate.")?; 2017 2018 let mut metadata = KeyMetaData::new(); 2019 metadata.add(KeyMetaEntry::CreationDate( 2020 DateTime::now().context("Trying to make creation time.")?, 2021 )); 2022 2023 metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?; 2024 2025 let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type) 2026 .context("Trying to rebind alias.")?; 2027 Ok(key_id).do_gc(need_gc) 2028 }) 2029 .context(ks_err!()) 2030 } 2031 2032 // Helper function loading the key_id given the key descriptor 2033 // tuple comprising domain, namespace, and alias. 2034 // Requires a valid transaction. load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64>2035 fn load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64> { 2036 let alias = key 2037 .alias 2038 .as_ref() 2039 .map_or_else(|| Err(KsError::sys()), Ok) 2040 .context("In load_key_entry_id: Alias must be specified.")?; 2041 let mut stmt = tx 2042 .prepare( 2043 "SELECT id FROM persistent.keyentry 2044 WHERE 2045 key_type = ? 2046 AND domain = ? 2047 AND namespace = ? 2048 AND alias = ? 2049 AND state = ?;", 2050 ) 2051 .context("In load_key_entry_id: Failed to select from keyentry table.")?; 2052 let mut rows = stmt 2053 .query(params![key_type, key.domain.0 as u32, key.nspace, alias, KeyLifeCycle::Live]) 2054 .context("In load_key_entry_id: Failed to read from keyentry table.")?; 2055 db_utils::with_rows_extract_one(&mut rows, |row| { 2056 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)? 2057 .get(0) 2058 .context("Failed to unpack id.") 2059 }) 2060 .context(ks_err!()) 2061 } 2062 2063 /// This helper function completes the access tuple of a key, which is required 2064 /// to perform access control. The strategy depends on the `domain` field in the 2065 /// key descriptor. 2066 /// * Domain::SELINUX: The access tuple is complete and this function only loads 2067 /// the key_id for further processing. 2068 /// * Domain::APP: Like Domain::SELINUX, but the tuple is completed by `caller_uid` 2069 /// which serves as the namespace. 2070 /// * Domain::GRANT: The grant table is queried for the `key_id` and the 2071 /// `access_vector`. 2072 /// * Domain::KEY_ID: The keyentry table is queried for the owning `domain` and 2073 /// `namespace`. 2074 /// 2075 /// In each case the information returned is sufficient to perform the access 2076 /// 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>2077 fn load_access_tuple( 2078 tx: &Transaction, 2079 key: &KeyDescriptor, 2080 key_type: KeyType, 2081 caller_uid: u32, 2082 ) -> Result<KeyAccessInfo> { 2083 match key.domain { 2084 // Domain App or SELinux. In this case we load the key_id from 2085 // the keyentry database for further loading of key components. 2086 // We already have the full access tuple to perform access control. 2087 // The only distinction is that we use the caller_uid instead 2088 // of the caller supplied namespace if the domain field is 2089 // Domain::APP. 2090 Domain::APP | Domain::SELINUX => { 2091 let mut access_key = key.clone(); 2092 if access_key.domain == Domain::APP { 2093 access_key.nspace = caller_uid as i64; 2094 } 2095 let key_id = Self::load_key_entry_id(tx, &access_key, key_type) 2096 .with_context(|| format!("With key.domain = {:?}.", access_key.domain))?; 2097 2098 Ok(KeyAccessInfo { key_id, descriptor: access_key, vector: None }) 2099 } 2100 2101 // Domain::GRANT. In this case we load the key_id and the access_vector 2102 // from the grant table. 2103 Domain::GRANT => { 2104 let mut stmt = tx 2105 .prepare( 2106 "SELECT keyentryid, access_vector FROM persistent.grant 2107 WHERE grantee = ? AND id = ? AND 2108 (SELECT state FROM persistent.keyentry WHERE id = keyentryid) = ?;", 2109 ) 2110 .context("Domain::GRANT prepare statement failed")?; 2111 let mut rows = stmt 2112 .query(params![caller_uid as i64, key.nspace, KeyLifeCycle::Live]) 2113 .context("Domain:Grant: query failed.")?; 2114 let (key_id, access_vector): (i64, i32) = 2115 db_utils::with_rows_extract_one(&mut rows, |row| { 2116 let r = 2117 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?; 2118 Ok(( 2119 r.get(0).context("Failed to unpack key_id.")?, 2120 r.get(1).context("Failed to unpack access_vector.")?, 2121 )) 2122 }) 2123 .context("Domain::GRANT.")?; 2124 Ok(KeyAccessInfo { 2125 key_id, 2126 descriptor: key.clone(), 2127 vector: Some(access_vector.into()), 2128 }) 2129 } 2130 2131 // Domain::KEY_ID. In this case we load the domain and namespace from the 2132 // keyentry database because we need them for access control. 2133 Domain::KEY_ID => { 2134 let (domain, namespace): (Domain, i64) = { 2135 let mut stmt = tx 2136 .prepare( 2137 "SELECT domain, namespace FROM persistent.keyentry 2138 WHERE 2139 id = ? 2140 AND state = ?;", 2141 ) 2142 .context("Domain::KEY_ID: prepare statement failed")?; 2143 let mut rows = stmt 2144 .query(params![key.nspace, KeyLifeCycle::Live]) 2145 .context("Domain::KEY_ID: query failed.")?; 2146 db_utils::with_rows_extract_one(&mut rows, |row| { 2147 let r = 2148 row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?; 2149 Ok(( 2150 Domain(r.get(0).context("Failed to unpack domain.")?), 2151 r.get(1).context("Failed to unpack namespace.")?, 2152 )) 2153 }) 2154 .context("Domain::KEY_ID.")? 2155 }; 2156 2157 // We may use a key by id after loading it by grant. 2158 // In this case we have to check if the caller has a grant for this particular 2159 // key. We can skip this if we already know that the caller is the owner. 2160 // But we cannot know this if domain is anything but App. E.g. in the case 2161 // of Domain::SELINUX we have to speculatively check for grants because we have to 2162 // consult the SEPolicy before we know if the caller is the owner. 2163 let access_vector: Option<KeyPermSet> = 2164 if domain != Domain::APP || namespace != caller_uid as i64 { 2165 let access_vector: Option<i32> = tx 2166 .query_row( 2167 "SELECT access_vector FROM persistent.grant 2168 WHERE grantee = ? AND keyentryid = ?;", 2169 params![caller_uid as i64, key.nspace], 2170 |row| row.get(0), 2171 ) 2172 .optional() 2173 .context("Domain::KEY_ID: query grant failed.")?; 2174 access_vector.map(|p| p.into()) 2175 } else { 2176 None 2177 }; 2178 2179 let key_id = key.nspace; 2180 let mut access_key: KeyDescriptor = key.clone(); 2181 access_key.domain = domain; 2182 access_key.nspace = namespace; 2183 2184 Ok(KeyAccessInfo { key_id, descriptor: access_key, vector: access_vector }) 2185 } 2186 _ => Err(anyhow!(KsError::Rc(ResponseCode::INVALID_ARGUMENT))), 2187 } 2188 } 2189 load_blob_components( key_id: i64, load_bits: KeyEntryLoadBits, tx: &Transaction, ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)>2190 fn load_blob_components( 2191 key_id: i64, 2192 load_bits: KeyEntryLoadBits, 2193 tx: &Transaction, 2194 ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)> { 2195 let mut stmt = tx 2196 .prepare( 2197 "SELECT MAX(id), subcomponent_type, blob FROM persistent.blobentry 2198 WHERE keyentryid = ? GROUP BY subcomponent_type;", 2199 ) 2200 .context(ks_err!("prepare statement failed."))?; 2201 2202 let mut rows = stmt.query(params![key_id]).context(ks_err!("query failed."))?; 2203 2204 let mut key_blob: Option<(i64, Vec<u8>)> = None; 2205 let mut cert_blob: Option<Vec<u8>> = None; 2206 let mut cert_chain_blob: Option<Vec<u8>> = None; 2207 let mut has_km_blob: bool = false; 2208 db_utils::with_rows_extract_all(&mut rows, |row| { 2209 let sub_type: SubComponentType = 2210 row.get(1).context("Failed to extract subcomponent_type.")?; 2211 has_km_blob = has_km_blob || sub_type == SubComponentType::KEY_BLOB; 2212 match (sub_type, load_bits.load_public(), load_bits.load_km()) { 2213 (SubComponentType::KEY_BLOB, _, true) => { 2214 key_blob = Some(( 2215 row.get(0).context("Failed to extract key blob id.")?, 2216 row.get(2).context("Failed to extract key blob.")?, 2217 )); 2218 } 2219 (SubComponentType::CERT, true, _) => { 2220 cert_blob = 2221 Some(row.get(2).context("Failed to extract public certificate blob.")?); 2222 } 2223 (SubComponentType::CERT_CHAIN, true, _) => { 2224 cert_chain_blob = 2225 Some(row.get(2).context("Failed to extract certificate chain blob.")?); 2226 } 2227 (SubComponentType::CERT, _, _) 2228 | (SubComponentType::CERT_CHAIN, _, _) 2229 | (SubComponentType::KEY_BLOB, _, _) => {} 2230 _ => Err(KsError::sys()).context("Unknown subcomponent type.")?, 2231 } 2232 Ok(()) 2233 }) 2234 .context(ks_err!())?; 2235 2236 let blob_info = key_blob.map_or::<Result<_>, _>(Ok(None), |(blob_id, blob)| { 2237 Ok(Some(( 2238 blob, 2239 BlobMetaData::load_from_db(blob_id, tx) 2240 .context(ks_err!("Trying to load blob_metadata."))?, 2241 ))) 2242 })?; 2243 2244 Ok((has_km_blob, blob_info, cert_blob, cert_chain_blob)) 2245 } 2246 load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>>2247 fn load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>> { 2248 let mut stmt = tx 2249 .prepare( 2250 "SELECT tag, data, security_level from persistent.keyparameter 2251 WHERE keyentryid = ?;", 2252 ) 2253 .context("In load_key_parameters: prepare statement failed.")?; 2254 2255 let mut parameters: Vec<KeyParameter> = Vec::new(); 2256 2257 let mut rows = 2258 stmt.query(params![key_id]).context("In load_key_parameters: query failed.")?; 2259 db_utils::with_rows_extract_all(&mut rows, |row| { 2260 let tag = Tag(row.get(0).context("Failed to read tag.")?); 2261 let sec_level = SecurityLevel(row.get(2).context("Failed to read sec_level.")?); 2262 parameters.push( 2263 KeyParameter::new_from_sql(tag, &SqlField::new(1, row), sec_level) 2264 .context("Failed to read KeyParameter.")?, 2265 ); 2266 Ok(()) 2267 }) 2268 .context(ks_err!())?; 2269 2270 Ok(parameters) 2271 } 2272 2273 /// Decrements the usage count of a limited use key. This function first checks whether the 2274 /// usage has been exhausted, if not, decreases the usage count. If the usage count reaches 2275 /// zero, the key also gets marked unreferenced and scheduled for deletion. 2276 /// 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<()>2277 pub fn check_and_update_key_usage_count(&mut self, key_id: i64) -> Result<()> { 2278 let _wp = wd::watch("KeystoreDB::check_and_update_key_usage_count"); 2279 2280 self.with_transaction(Immediate("TX_check_and_update_key_usage_count"), |tx| { 2281 let limit: Option<i32> = tx 2282 .query_row( 2283 "SELECT data FROM persistent.keyparameter WHERE keyentryid = ? AND tag = ?;", 2284 params![key_id, Tag::USAGE_COUNT_LIMIT.0], 2285 |row| row.get(0), 2286 ) 2287 .optional() 2288 .context("Trying to load usage count")?; 2289 2290 let limit = limit 2291 .ok_or(KsError::Km(ErrorCode::INVALID_KEY_BLOB)) 2292 .context("The Key no longer exists. Key is exhausted.")?; 2293 2294 tx.execute( 2295 "UPDATE persistent.keyparameter 2296 SET data = data - 1 2297 WHERE keyentryid = ? AND tag = ? AND data > 0;", 2298 params![key_id, Tag::USAGE_COUNT_LIMIT.0], 2299 ) 2300 .context("Failed to update key usage count.")?; 2301 2302 match limit { 2303 1 => Self::mark_unreferenced(tx, key_id) 2304 .map(|need_gc| (need_gc, ())) 2305 .context("Trying to mark limited use key for deletion."), 2306 0 => Err(KsError::Km(ErrorCode::INVALID_KEY_BLOB)).context("Key is exhausted."), 2307 _ => Ok(()).no_gc(), 2308 } 2309 }) 2310 .context(ks_err!()) 2311 } 2312 2313 /// Load a key entry by the given key descriptor. 2314 /// It uses the `check_permission` callback to verify if the access is allowed 2315 /// given the key access tuple read from the database using `load_access_tuple`. 2316 /// With `load_bits` the caller may specify which blobs shall be loaded from 2317 /// 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)>2318 pub fn load_key_entry( 2319 &mut self, 2320 key: &KeyDescriptor, 2321 key_type: KeyType, 2322 load_bits: KeyEntryLoadBits, 2323 caller_uid: u32, 2324 check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2325 ) -> Result<(KeyIdGuard, KeyEntry)> { 2326 let _wp = wd::watch("KeystoreDB::load_key_entry"); 2327 2328 loop { 2329 match self.load_key_entry_internal( 2330 key, 2331 key_type, 2332 load_bits, 2333 caller_uid, 2334 &check_permission, 2335 ) { 2336 Ok(result) => break Ok(result), 2337 Err(e) => { 2338 if Self::is_locked_error(&e) { 2339 std::thread::sleep(DB_BUSY_RETRY_INTERVAL); 2340 continue; 2341 } else { 2342 return Err(e).context(ks_err!()); 2343 } 2344 } 2345 } 2346 } 2347 } 2348 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)>2349 fn load_key_entry_internal( 2350 &mut self, 2351 key: &KeyDescriptor, 2352 key_type: KeyType, 2353 load_bits: KeyEntryLoadBits, 2354 caller_uid: u32, 2355 check_permission: &impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2356 ) -> Result<(KeyIdGuard, KeyEntry)> { 2357 // KEY ID LOCK 1/2 2358 // If we got a key descriptor with a key id we can get the lock right away. 2359 // Otherwise we have to defer it until we know the key id. 2360 let key_id_guard = match key.domain { 2361 Domain::KEY_ID => Some(KEY_ID_LOCK.get(key.nspace)), 2362 _ => None, 2363 }; 2364 2365 let tx = self 2366 .conn 2367 .unchecked_transaction() 2368 .context(ks_err!("Failed to initialize transaction."))?; 2369 2370 // Load the key_id and complete the access control tuple. 2371 let access = Self::load_access_tuple(&tx, key, key_type, caller_uid).context(ks_err!())?; 2372 2373 // Perform access control. It is vital that we return here if the permission is denied. 2374 // So do not touch that '?' at the end. 2375 check_permission(&access.descriptor, access.vector).context(ks_err!())?; 2376 2377 // KEY ID LOCK 2/2 2378 // If we did not get a key id lock by now, it was because we got a key descriptor 2379 // without a key id. At this point we got the key id, so we can try and get a lock. 2380 // However, we cannot block here, because we are in the middle of the transaction. 2381 // So first we try to get the lock non blocking. If that fails, we roll back the 2382 // transaction and block until we get the lock. After we successfully got the lock, 2383 // we start a new transaction and load the access tuple again. 2384 // 2385 // We don't need to perform access control again, because we already established 2386 // that the caller had access to the given key. But we need to make sure that the 2387 // key id still exists. So we have to load the key entry by key id this time. 2388 let (key_id_guard, tx) = match key_id_guard { 2389 None => match KEY_ID_LOCK.try_get(access.key_id) { 2390 None => { 2391 // Roll back the transaction. 2392 tx.rollback().context(ks_err!("Failed to roll back transaction."))?; 2393 2394 // Block until we have a key id lock. 2395 let key_id_guard = KEY_ID_LOCK.get(access.key_id); 2396 2397 // Create a new transaction. 2398 let tx = self 2399 .conn 2400 .unchecked_transaction() 2401 .context(ks_err!("Failed to initialize transaction."))?; 2402 2403 Self::load_access_tuple( 2404 &tx, 2405 // This time we have to load the key by the retrieved key id, because the 2406 // alias may have been rebound after we rolled back the transaction. 2407 &KeyDescriptor { 2408 domain: Domain::KEY_ID, 2409 nspace: access.key_id, 2410 ..Default::default() 2411 }, 2412 key_type, 2413 caller_uid, 2414 ) 2415 .context(ks_err!("(deferred key lock)"))?; 2416 (key_id_guard, tx) 2417 } 2418 Some(l) => (l, tx), 2419 }, 2420 Some(key_id_guard) => (key_id_guard, tx), 2421 }; 2422 2423 let key_entry = 2424 Self::load_key_components(&tx, load_bits, key_id_guard.id()).context(ks_err!())?; 2425 2426 tx.commit().context(ks_err!("Failed to commit transaction."))?; 2427 2428 Ok((key_id_guard, key_entry)) 2429 } 2430 mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool>2431 fn mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool> { 2432 let updated = tx 2433 .execute("DELETE FROM persistent.keyentry WHERE id = ?;", params![key_id]) 2434 .context("Trying to delete keyentry.")?; 2435 tx.execute("DELETE FROM persistent.keymetadata WHERE keyentryid = ?;", params![key_id]) 2436 .context("Trying to delete keymetadata.")?; 2437 tx.execute("DELETE FROM persistent.keyparameter WHERE keyentryid = ?;", params![key_id]) 2438 .context("Trying to delete keyparameters.")?; 2439 tx.execute("DELETE FROM persistent.grant WHERE keyentryid = ?;", params![key_id]) 2440 .context("Trying to delete grants.")?; 2441 // The associated blobentry rows are not immediately deleted when the owning keyentry is 2442 // removed, because a KeyMint `deleteKey()` invocation is needed (specifically for the 2443 // `KEY_BLOB`). Mark the affected rows with `state=Orphaned` so a subsequent garbage 2444 // collection can do this. 2445 tx.execute( 2446 "UPDATE persistent.blobentry SET state = ? WHERE keyentryid = ?", 2447 params![BlobState::Orphaned, key_id], 2448 ) 2449 .context("Trying to mark blobentrys as superseded")?; 2450 Ok(updated != 0) 2451 } 2452 2453 /// Marks the given key as unreferenced and removes all of the grants to this key. 2454 /// 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<()>2455 pub fn unbind_key( 2456 &mut self, 2457 key: &KeyDescriptor, 2458 key_type: KeyType, 2459 caller_uid: u32, 2460 check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>, 2461 ) -> Result<()> { 2462 let _wp = wd::watch("KeystoreDB::unbind_key"); 2463 2464 self.with_transaction(Immediate("TX_unbind_key"), |tx| { 2465 let access = Self::load_access_tuple(tx, key, key_type, caller_uid) 2466 .context("Trying to get access tuple.")?; 2467 2468 // Perform access control. It is vital that we return here if the permission is denied. 2469 // So do not touch that '?' at the end. 2470 check_permission(&access.descriptor, access.vector) 2471 .context("While checking permission.")?; 2472 2473 Self::mark_unreferenced(tx, access.key_id) 2474 .map(|need_gc| (need_gc, ())) 2475 .context("Trying to mark the key unreferenced.") 2476 }) 2477 .context(ks_err!()) 2478 } 2479 get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid>2480 fn get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid> { 2481 tx.query_row( 2482 "SELECT km_uuid FROM persistent.keyentry WHERE id = ?", 2483 params![key_id], 2484 |row| row.get(0), 2485 ) 2486 .context(ks_err!()) 2487 } 2488 2489 /// Delete all artifacts belonging to the namespace given by the domain-namespace tuple. 2490 /// This leaves all of the blob entries orphaned for subsequent garbage collection. unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()>2491 pub fn unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()> { 2492 let _wp = wd::watch("KeystoreDB::unbind_keys_for_namespace"); 2493 2494 if !(domain == Domain::APP || domain == Domain::SELINUX) { 2495 return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!()); 2496 } 2497 self.with_transaction(Immediate("TX_unbind_keys_for_namespace"), |tx| { 2498 tx.execute( 2499 "DELETE FROM persistent.keymetadata 2500 WHERE keyentryid IN ( 2501 SELECT id FROM persistent.keyentry 2502 WHERE domain = ? AND namespace = ? AND key_type = ? 2503 );", 2504 params![domain.0, namespace, KeyType::Client], 2505 ) 2506 .context("Trying to delete keymetadata.")?; 2507 tx.execute( 2508 "DELETE FROM persistent.keyparameter 2509 WHERE keyentryid IN ( 2510 SELECT id FROM persistent.keyentry 2511 WHERE domain = ? AND namespace = ? AND key_type = ? 2512 );", 2513 params![domain.0, namespace, KeyType::Client], 2514 ) 2515 .context("Trying to delete keyparameters.")?; 2516 tx.execute( 2517 "DELETE FROM persistent.grant 2518 WHERE keyentryid IN ( 2519 SELECT id FROM persistent.keyentry 2520 WHERE domain = ? AND namespace = ? AND key_type = ? 2521 );", 2522 params![domain.0, namespace, KeyType::Client], 2523 ) 2524 .context("Trying to delete grants.")?; 2525 tx.execute( 2526 "DELETE FROM persistent.keyentry 2527 WHERE domain = ? AND namespace = ? AND key_type = ?;", 2528 params![domain.0, namespace, KeyType::Client], 2529 ) 2530 .context("Trying to delete keyentry.")?; 2531 Ok(()).need_gc() 2532 }) 2533 .context(ks_err!()) 2534 } 2535 cleanup_unreferenced(tx: &Transaction) -> Result<()>2536 fn cleanup_unreferenced(tx: &Transaction) -> Result<()> { 2537 let _wp = wd::watch("KeystoreDB::cleanup_unreferenced"); 2538 { 2539 tx.execute( 2540 "DELETE FROM persistent.keymetadata 2541 WHERE keyentryid IN ( 2542 SELECT id FROM persistent.keyentry 2543 WHERE state = ? 2544 );", 2545 params![KeyLifeCycle::Unreferenced], 2546 ) 2547 .context("Trying to delete keymetadata.")?; 2548 tx.execute( 2549 "DELETE FROM persistent.keyparameter 2550 WHERE keyentryid IN ( 2551 SELECT id FROM persistent.keyentry 2552 WHERE state = ? 2553 );", 2554 params![KeyLifeCycle::Unreferenced], 2555 ) 2556 .context("Trying to delete keyparameters.")?; 2557 tx.execute( 2558 "DELETE FROM persistent.grant 2559 WHERE keyentryid IN ( 2560 SELECT id FROM persistent.keyentry 2561 WHERE state = ? 2562 );", 2563 params![KeyLifeCycle::Unreferenced], 2564 ) 2565 .context("Trying to delete grants.")?; 2566 tx.execute( 2567 "DELETE FROM persistent.keyentry 2568 WHERE state = ?;", 2569 params![KeyLifeCycle::Unreferenced], 2570 ) 2571 .context("Trying to delete keyentry.")?; 2572 Result::<()>::Ok(()) 2573 } 2574 .context(ks_err!()) 2575 } 2576 2577 /// Deletes all keys for the given user, including both client keys and super keys. unbind_keys_for_user(&mut self, user_id: u32) -> Result<()>2578 pub fn unbind_keys_for_user(&mut self, user_id: u32) -> Result<()> { 2579 let _wp = wd::watch("KeystoreDB::unbind_keys_for_user"); 2580 2581 self.with_transaction(Immediate("TX_unbind_keys_for_user"), |tx| { 2582 let mut stmt = tx 2583 .prepare(&format!( 2584 "SELECT id from persistent.keyentry 2585 WHERE ( 2586 key_type = ? 2587 AND domain = ? 2588 AND cast ( (namespace/{aid_user_offset}) as int) = ? 2589 AND state = ? 2590 ) OR ( 2591 key_type = ? 2592 AND namespace = ? 2593 AND state = ? 2594 );", 2595 aid_user_offset = AID_USER_OFFSET 2596 )) 2597 .context(concat!( 2598 "In unbind_keys_for_user. ", 2599 "Failed to prepare the query to find the keys created by apps." 2600 ))?; 2601 2602 let mut rows = stmt 2603 .query(params![ 2604 // WHERE client key: 2605 KeyType::Client, 2606 Domain::APP.0 as u32, 2607 user_id, 2608 KeyLifeCycle::Live, 2609 // OR super key: 2610 KeyType::Super, 2611 user_id, 2612 KeyLifeCycle::Live 2613 ]) 2614 .context(ks_err!("Failed to query the keys created by apps."))?; 2615 2616 let mut key_ids: Vec<i64> = Vec::new(); 2617 db_utils::with_rows_extract_all(&mut rows, |row| { 2618 key_ids 2619 .push(row.get(0).context("Failed to read key id of a key created by an app.")?); 2620 Ok(()) 2621 }) 2622 .context(ks_err!())?; 2623 2624 let mut notify_gc = false; 2625 for key_id in key_ids { 2626 notify_gc = Self::mark_unreferenced(tx, key_id) 2627 .context("In unbind_keys_for_user.")? 2628 || notify_gc; 2629 } 2630 Ok(()).do_gc(notify_gc) 2631 }) 2632 .context(ks_err!()) 2633 } 2634 2635 /// Deletes all auth-bound keys, i.e. keys that require user authentication, for the given user. 2636 /// This runs when the user's lock screen is being changed to Swipe or None. 2637 /// 2638 /// This intentionally does *not* delete keys that require that the device be unlocked, unless 2639 /// such keys also require user authentication. Keystore's concept of user authentication is 2640 /// fairly strong, and it requires that keys that require authentication be deleted as soon as 2641 /// authentication is no longer possible. In contrast, keys that just require that the device 2642 /// be unlocked should remain usable when the lock screen is set to Swipe or None, as the device 2643 /// is always considered "unlocked" in that case. unbind_auth_bound_keys_for_user(&mut self, user_id: u32) -> Result<()>2644 pub fn unbind_auth_bound_keys_for_user(&mut self, user_id: u32) -> Result<()> { 2645 let _wp = wd::watch("KeystoreDB::unbind_auth_bound_keys_for_user"); 2646 2647 self.with_transaction(Immediate("TX_unbind_auth_bound_keys_for_user"), |tx| { 2648 let mut stmt = tx 2649 .prepare(&format!( 2650 "SELECT id from persistent.keyentry 2651 WHERE key_type = ? 2652 AND domain = ? 2653 AND cast ( (namespace/{aid_user_offset}) as int) = ? 2654 AND state = ?;", 2655 aid_user_offset = AID_USER_OFFSET 2656 )) 2657 .context(concat!( 2658 "In unbind_auth_bound_keys_for_user. ", 2659 "Failed to prepare the query to find the keys created by apps." 2660 ))?; 2661 2662 let mut rows = stmt 2663 .query(params![KeyType::Client, Domain::APP.0 as u32, user_id, KeyLifeCycle::Live,]) 2664 .context(ks_err!("Failed to query the keys created by apps."))?; 2665 2666 let mut key_ids: Vec<i64> = Vec::new(); 2667 db_utils::with_rows_extract_all(&mut rows, |row| { 2668 key_ids 2669 .push(row.get(0).context("Failed to read key id of a key created by an app.")?); 2670 Ok(()) 2671 }) 2672 .context(ks_err!())?; 2673 2674 let mut notify_gc = false; 2675 let mut num_unbound = 0; 2676 for key_id in key_ids { 2677 // Load the key parameters and filter out non-auth-bound keys. To identify 2678 // auth-bound keys, use the presence of UserSecureID. The absence of NoAuthRequired 2679 // could also be used, but UserSecureID is what Keystore treats as authoritative 2680 // when actually enforcing the key parameters (it might not matter, though). 2681 let params = Self::load_key_parameters(key_id, tx) 2682 .context("Failed to load key parameters.")?; 2683 let is_auth_bound_key = params.iter().any(|kp| { 2684 matches!(kp.key_parameter_value(), KeyParameterValue::UserSecureID(_)) 2685 }); 2686 if is_auth_bound_key { 2687 notify_gc = Self::mark_unreferenced(tx, key_id) 2688 .context("In unbind_auth_bound_keys_for_user.")? 2689 || notify_gc; 2690 num_unbound += 1; 2691 } 2692 } 2693 log::info!("Deleting {num_unbound} auth-bound keys for user {user_id}"); 2694 Ok(()).do_gc(notify_gc) 2695 }) 2696 .context(ks_err!()) 2697 } 2698 load_key_components( tx: &Transaction, load_bits: KeyEntryLoadBits, key_id: i64, ) -> Result<KeyEntry>2699 fn load_key_components( 2700 tx: &Transaction, 2701 load_bits: KeyEntryLoadBits, 2702 key_id: i64, 2703 ) -> Result<KeyEntry> { 2704 let metadata = KeyMetaData::load_from_db(key_id, tx).context("In load_key_components.")?; 2705 2706 let (has_km_blob, key_blob_info, cert_blob, cert_chain_blob) = 2707 Self::load_blob_components(key_id, load_bits, tx).context("In load_key_components.")?; 2708 2709 let parameters = Self::load_key_parameters(key_id, tx) 2710 .context("In load_key_components: Trying to load key parameters.")?; 2711 2712 let km_uuid = Self::get_key_km_uuid(tx, key_id) 2713 .context("In load_key_components: Trying to get KM uuid.")?; 2714 2715 Ok(KeyEntry { 2716 id: key_id, 2717 key_blob_info, 2718 cert: cert_blob, 2719 cert_chain: cert_chain_blob, 2720 km_uuid, 2721 parameters, 2722 metadata, 2723 pure_cert: !has_km_blob, 2724 }) 2725 } 2726 2727 /// Returns a list of KeyDescriptors in the selected domain/namespace whose 2728 /// aliases are greater than the specified 'start_past_alias'. If no value 2729 /// is provided, returns all KeyDescriptors. 2730 /// The key descriptors will have the domain, nspace, and alias field set. 2731 /// The returned list will be sorted by alias. 2732 /// Domain must be APP or SELINUX, the caller must make sure of that. 2733 /// Number of returned values is limited to 10,000 (which is empirically roughly 2734 /// 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>>2735 pub fn list_past_alias( 2736 &mut self, 2737 domain: Domain, 2738 namespace: i64, 2739 key_type: KeyType, 2740 start_past_alias: Option<&str>, 2741 ) -> Result<Vec<KeyDescriptor>> { 2742 let _wp = wd::watch("KeystoreDB::list_past_alias"); 2743 2744 let query = format!( 2745 "SELECT DISTINCT alias FROM persistent.keyentry 2746 WHERE domain = ? 2747 AND namespace = ? 2748 AND alias IS NOT NULL 2749 AND state = ? 2750 AND key_type = ? 2751 {} 2752 ORDER BY alias ASC 2753 LIMIT 10000;", 2754 if start_past_alias.is_some() { " AND alias > ?" } else { "" } 2755 ); 2756 2757 self.with_transaction(TransactionBehavior::Deferred, |tx| { 2758 let mut stmt = tx.prepare(&query).context(ks_err!("Failed to prepare."))?; 2759 2760 let mut rows = match start_past_alias { 2761 Some(past_alias) => stmt 2762 .query(params![ 2763 domain.0 as u32, 2764 namespace, 2765 KeyLifeCycle::Live, 2766 key_type, 2767 past_alias 2768 ]) 2769 .context(ks_err!("Failed to query."))?, 2770 None => stmt 2771 .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type,]) 2772 .context(ks_err!("Failed to query."))?, 2773 }; 2774 2775 let mut descriptors: Vec<KeyDescriptor> = Vec::new(); 2776 db_utils::with_rows_extract_all(&mut rows, |row| { 2777 descriptors.push(KeyDescriptor { 2778 domain, 2779 nspace: namespace, 2780 alias: Some(row.get(0).context("Trying to extract alias.")?), 2781 blob: None, 2782 }); 2783 Ok(()) 2784 }) 2785 .context(ks_err!("Failed to extract rows."))?; 2786 Ok(descriptors).no_gc() 2787 }) 2788 } 2789 2790 /// Returns a number of KeyDescriptors in the selected domain/namespace. 2791 /// 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>2792 pub fn count_keys( 2793 &mut self, 2794 domain: Domain, 2795 namespace: i64, 2796 key_type: KeyType, 2797 ) -> Result<usize> { 2798 let _wp = wd::watch("KeystoreDB::countKeys"); 2799 2800 let num_keys = self.with_transaction(TransactionBehavior::Deferred, |tx| { 2801 tx.query_row( 2802 "SELECT COUNT(alias) FROM persistent.keyentry 2803 WHERE domain = ? 2804 AND namespace = ? 2805 AND alias IS NOT NULL 2806 AND state = ? 2807 AND key_type = ?;", 2808 params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type], 2809 |row| row.get(0), 2810 ) 2811 .context(ks_err!("Failed to count number of keys.")) 2812 .no_gc() 2813 })?; 2814 Ok(num_keys) 2815 } 2816 2817 /// Adds a grant to the grant table. 2818 /// Like `load_key_entry` this function loads the access tuple before 2819 /// it uses the callback for a permission check. Upon success, 2820 /// it inserts the `grantee_uid`, `key_id`, and `access_vector` into the 2821 /// grant table. The new row will have a randomized id, which is used as 2822 /// 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>2823 pub fn grant( 2824 &mut self, 2825 key: &KeyDescriptor, 2826 caller_uid: u32, 2827 grantee_uid: u32, 2828 access_vector: KeyPermSet, 2829 check_permission: impl Fn(&KeyDescriptor, &KeyPermSet) -> Result<()>, 2830 ) -> Result<KeyDescriptor> { 2831 let _wp = wd::watch("KeystoreDB::grant"); 2832 2833 self.with_transaction(Immediate("TX_grant"), |tx| { 2834 // Load the key_id and complete the access control tuple. 2835 // We ignore the access vector here because grants cannot be granted. 2836 // The access vector returned here expresses the permissions the 2837 // grantee has if key.domain == Domain::GRANT. But this vector 2838 // cannot include the grant permission by design, so there is no way the 2839 // subsequent permission check can pass. 2840 // We could check key.domain == Domain::GRANT and fail early. 2841 // But even if we load the access tuple by grant here, the permission 2842 // check denies the attempt to create a grant by grant descriptor. 2843 let access = 2844 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid).context(ks_err!())?; 2845 2846 // Perform access control. It is vital that we return here if the permission 2847 // was denied. So do not touch that '?' at the end of the line. 2848 // This permission check checks if the caller has the grant permission 2849 // for the given key and in addition to all of the permissions 2850 // expressed in `access_vector`. 2851 check_permission(&access.descriptor, &access_vector) 2852 .context(ks_err!("check_permission failed"))?; 2853 2854 let grant_id = if let Some(grant_id) = tx 2855 .query_row( 2856 "SELECT id FROM persistent.grant 2857 WHERE keyentryid = ? AND grantee = ?;", 2858 params![access.key_id, grantee_uid], 2859 |row| row.get(0), 2860 ) 2861 .optional() 2862 .context(ks_err!("Failed get optional existing grant id."))? 2863 { 2864 tx.execute( 2865 "UPDATE persistent.grant 2866 SET access_vector = ? 2867 WHERE id = ?;", 2868 params![i32::from(access_vector), grant_id], 2869 ) 2870 .context(ks_err!("Failed to update existing grant."))?; 2871 grant_id 2872 } else { 2873 Self::insert_with_retry(|id| { 2874 tx.execute( 2875 "INSERT INTO persistent.grant (id, grantee, keyentryid, access_vector) 2876 VALUES (?, ?, ?, ?);", 2877 params![id, grantee_uid, access.key_id, i32::from(access_vector)], 2878 ) 2879 }) 2880 .context(ks_err!())? 2881 }; 2882 2883 Ok(KeyDescriptor { domain: Domain::GRANT, nspace: grant_id, alias: None, blob: None }) 2884 .no_gc() 2885 }) 2886 } 2887 2888 /// This function checks permissions like `grant` and `load_key_entry` 2889 /// 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<()>2890 pub fn ungrant( 2891 &mut self, 2892 key: &KeyDescriptor, 2893 caller_uid: u32, 2894 grantee_uid: u32, 2895 check_permission: impl Fn(&KeyDescriptor) -> Result<()>, 2896 ) -> Result<()> { 2897 let _wp = wd::watch("KeystoreDB::ungrant"); 2898 2899 self.with_transaction(Immediate("TX_ungrant"), |tx| { 2900 // Load the key_id and complete the access control tuple. 2901 // We ignore the access vector here because grants cannot be granted. 2902 let access = 2903 Self::load_access_tuple(tx, key, KeyType::Client, caller_uid).context(ks_err!())?; 2904 2905 // Perform access control. We must return here if the permission 2906 // was denied. So do not touch the '?' at the end of this line. 2907 check_permission(&access.descriptor).context(ks_err!("check_permission failed."))?; 2908 2909 tx.execute( 2910 "DELETE FROM persistent.grant 2911 WHERE keyentryid = ? AND grantee = ?;", 2912 params![access.key_id, grantee_uid], 2913 ) 2914 .context("Failed to delete grant.")?; 2915 2916 Ok(()).no_gc() 2917 }) 2918 } 2919 2920 // Generates a random id and passes it to the given function, which will 2921 // try to insert it into a database. If that insertion fails, retry; 2922 // otherwise return the id. insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64>2923 fn insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64> { 2924 loop { 2925 let newid: i64 = match random() { 2926 Self::UNASSIGNED_KEY_ID => continue, // UNASSIGNED_KEY_ID cannot be assigned. 2927 i => i, 2928 }; 2929 match inserter(newid) { 2930 // If the id already existed, try again. 2931 Err(rusqlite::Error::SqliteFailure( 2932 libsqlite3_sys::Error { 2933 code: libsqlite3_sys::ErrorCode::ConstraintViolation, 2934 extended_code: libsqlite3_sys::SQLITE_CONSTRAINT_UNIQUE, 2935 }, 2936 _, 2937 )) => (), 2938 Err(e) => { 2939 return Err(e).context(ks_err!("failed to insert into database.")); 2940 } 2941 _ => return Ok(newid), 2942 } 2943 } 2944 } 2945 2946 /// Insert or replace the auth token based on (user_id, auth_id, auth_type) insert_auth_token(&mut self, auth_token: &HardwareAuthToken)2947 pub fn insert_auth_token(&mut self, auth_token: &HardwareAuthToken) { 2948 self.perboot 2949 .insert_auth_token_entry(AuthTokenEntry::new(auth_token.clone(), BootTime::now())) 2950 } 2951 2952 /// Find the newest auth token matching the given predicate. find_auth_token_entry<F>(&self, p: F) -> Option<AuthTokenEntry> where F: Fn(&AuthTokenEntry) -> bool,2953 pub fn find_auth_token_entry<F>(&self, p: F) -> Option<AuthTokenEntry> 2954 where 2955 F: Fn(&AuthTokenEntry) -> bool, 2956 { 2957 self.perboot.find_auth_token_entry(p) 2958 } 2959 2960 /// Load descriptor of a key by key id load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>>2961 pub fn load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>> { 2962 let _wp = wd::watch("KeystoreDB::load_key_descriptor"); 2963 2964 self.with_transaction(TransactionBehavior::Deferred, |tx| { 2965 tx.query_row( 2966 "SELECT domain, namespace, alias FROM persistent.keyentry WHERE id = ?;", 2967 params![key_id], 2968 |row| { 2969 Ok(KeyDescriptor { 2970 domain: Domain(row.get(0)?), 2971 nspace: row.get(1)?, 2972 alias: row.get(2)?, 2973 blob: None, 2974 }) 2975 }, 2976 ) 2977 .optional() 2978 .context("Trying to load key descriptor") 2979 .no_gc() 2980 }) 2981 .context(ks_err!()) 2982 } 2983 2984 /// Returns a list of app UIDs that have keys authenticated by the given secure_user_id 2985 /// (for the given user_id). 2986 /// This is helpful for finding out which apps will have their keys invalidated when 2987 /// 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>>2988 pub fn get_app_uids_affected_by_sid( 2989 &mut self, 2990 user_id: i32, 2991 secure_user_id: i64, 2992 ) -> Result<Vec<i64>> { 2993 let _wp = wd::watch("KeystoreDB::get_app_uids_affected_by_sid"); 2994 2995 let ids = self.with_transaction(Immediate("TX_get_app_uids_affected_by_sid"), |tx| { 2996 let mut stmt = tx 2997 .prepare(&format!( 2998 "SELECT id, namespace from persistent.keyentry 2999 WHERE key_type = ? 3000 AND domain = ? 3001 AND cast ( (namespace/{AID_USER_OFFSET}) as int) = ? 3002 AND state = ?;", 3003 )) 3004 .context(concat!( 3005 "In get_app_uids_affected_by_sid, ", 3006 "failed to prepare the query to find the keys created by apps." 3007 ))?; 3008 3009 let mut rows = stmt 3010 .query(params![KeyType::Client, Domain::APP.0 as u32, user_id, KeyLifeCycle::Live,]) 3011 .context(ks_err!("Failed to query the keys created by apps."))?; 3012 3013 let mut key_ids_and_app_uids: HashMap<i64, i64> = Default::default(); 3014 db_utils::with_rows_extract_all(&mut rows, |row| { 3015 key_ids_and_app_uids.insert( 3016 row.get(0).context("Failed to read key id of a key created by an app.")?, 3017 row.get(1).context("Failed to read the app uid")?, 3018 ); 3019 Ok(()) 3020 })?; 3021 Ok(key_ids_and_app_uids).no_gc() 3022 })?; 3023 let mut app_uids_affected_by_sid: HashSet<i64> = Default::default(); 3024 for (key_id, app_uid) in ids { 3025 // Read the key parameters for each key in its own transaction. It is OK to ignore 3026 // an error to get the properties of a particular key since it might have been deleted 3027 // under our feet after the previous transaction concluded. If the key was deleted 3028 // then it is no longer applicable if it was auth-bound or not. 3029 if let Ok(is_key_bound_to_sid) = 3030 self.with_transaction(Immediate("TX_get_app_uids_affects_by_sid 2"), |tx| { 3031 let params = Self::load_key_parameters(key_id, tx) 3032 .context("Failed to load key parameters.")?; 3033 // Check if the key is bound to this secure user ID. 3034 let is_key_bound_to_sid = params.iter().any(|kp| { 3035 matches!( 3036 kp.key_parameter_value(), 3037 KeyParameterValue::UserSecureID(sid) if *sid == secure_user_id 3038 ) 3039 }); 3040 Ok(is_key_bound_to_sid).no_gc() 3041 }) 3042 { 3043 if is_key_bound_to_sid { 3044 app_uids_affected_by_sid.insert(app_uid); 3045 } 3046 } 3047 } 3048 3049 let app_uids_vec: Vec<i64> = app_uids_affected_by_sid.into_iter().collect(); 3050 Ok(app_uids_vec) 3051 } 3052 } 3053