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