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 crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0 16 //! AIDL spec. 17 18 use std::collections::HashMap; 19 20 use crate::audit_log::log_key_deleted; 21 use crate::permission::{KeyPerm, KeystorePerm}; 22 use crate::security_level::KeystoreSecurityLevel; 23 use crate::utils::{ 24 check_grant_permission, check_key_permission, check_keystore_permission, 25 key_parameters_to_authorizations, watchdog as wd, Asp, 26 }; 27 use crate::{ 28 database::Uuid, 29 globals::{create_thread_local_db, DB, LEGACY_BLOB_LOADER, LEGACY_MIGRATOR}, 30 }; 31 use crate::{database::KEYSTORE_UUID, permission}; 32 use crate::{ 33 database::{KeyEntryLoadBits, KeyType, SubComponentType}, 34 error::ResponseCode, 35 }; 36 use crate::{ 37 error::{self, map_or_log_err, ErrorCode}, 38 id_rotation::IdRotationState, 39 }; 40 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel; 41 use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState}; 42 use android_system_keystore2::aidl::android::system::keystore2::{ 43 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, 44 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService, 45 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata, 46 }; 47 use anyhow::{Context, Result}; 48 use error::Error; 49 use keystore2_selinux as selinux; 50 51 /// Implementation of the IKeystoreService. 52 #[derive(Default)] 53 pub struct KeystoreService { 54 i_sec_level_by_uuid: HashMap<Uuid, Asp>, 55 uuid_by_sec_level: HashMap<SecurityLevel, Uuid>, 56 } 57 58 impl KeystoreService { 59 /// Create a new instance of the Keystore 2.0 service. new_native_binder( id_rotation_state: IdRotationState, ) -> Result<Strong<dyn IKeystoreService>>60 pub fn new_native_binder( 61 id_rotation_state: IdRotationState, 62 ) -> Result<Strong<dyn IKeystoreService>> { 63 let mut result: Self = Default::default(); 64 let (dev, uuid) = KeystoreSecurityLevel::new_native_binder( 65 SecurityLevel::TRUSTED_ENVIRONMENT, 66 id_rotation_state.clone(), 67 ) 68 .context(concat!( 69 "In KeystoreService::new_native_binder: ", 70 "Trying to construct mandatory security level TEE." 71 )) 72 .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))?; 73 result.i_sec_level_by_uuid.insert(uuid, dev); 74 result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid); 75 76 // Strongbox is optional, so we ignore errors and turn the result into an Option. 77 if let Ok((dev, uuid)) = 78 KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state) 79 .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid)) 80 { 81 result.i_sec_level_by_uuid.insert(uuid, dev); 82 result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid); 83 } 84 85 let uuid_by_sec_level = result.uuid_by_sec_level.clone(); 86 LEGACY_MIGRATOR 87 .set_init(move || { 88 (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone()) 89 }) 90 .context( 91 "In KeystoreService::new_native_binder: Trying to initialize the legacy migrator.", 92 )?; 93 94 Ok(BnKeystoreService::new_binder( 95 result, 96 BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() }, 97 )) 98 } 99 uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel100 fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel { 101 self.uuid_by_sec_level 102 .iter() 103 .find(|(_, v)| **v == *uuid) 104 .map(|(s, _)| *s) 105 .unwrap_or(SecurityLevel::SOFTWARE) 106 } 107 get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>>108 fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> { 109 if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) { 110 dev.get_interface().context("In get_i_sec_level_by_uuid.") 111 } else { 112 Err(error::Error::sys()) 113 .context("In get_i_sec_level_by_uuid: KeyMint instance for key not found.") 114 } 115 } 116 get_security_level( &self, sec_level: SecurityLevel, ) -> Result<Strong<dyn IKeystoreSecurityLevel>>117 fn get_security_level( 118 &self, 119 sec_level: SecurityLevel, 120 ) -> Result<Strong<dyn IKeystoreSecurityLevel>> { 121 if let Some(dev) = self 122 .uuid_by_sec_level 123 .get(&sec_level) 124 .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid)) 125 { 126 dev.get_interface().context("In get_security_level.") 127 } else { 128 Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) 129 .context("In get_security_level: No such security level.") 130 } 131 } 132 get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse>133 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> { 134 let caller_uid = ThreadState::get_calling_uid(); 135 let (key_id_guard, mut key_entry) = DB 136 .with(|db| { 137 LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || { 138 db.borrow_mut().load_key_entry( 139 &key, 140 KeyType::Client, 141 KeyEntryLoadBits::PUBLIC, 142 caller_uid, 143 |k, av| check_key_permission(KeyPerm::get_info(), k, &av), 144 ) 145 }) 146 }) 147 .context("In get_key_entry, while trying to load key info.")?; 148 149 let i_sec_level = if !key_entry.pure_cert() { 150 Some( 151 self.get_i_sec_level_by_uuid(key_entry.km_uuid()) 152 .context("In get_key_entry: Trying to get security level proxy.")?, 153 ) 154 } else { 155 None 156 }; 157 158 Ok(KeyEntryResponse { 159 iSecurityLevel: i_sec_level, 160 metadata: KeyMetadata { 161 key: KeyDescriptor { 162 domain: Domain::KEY_ID, 163 nspace: key_id_guard.id(), 164 ..Default::default() 165 }, 166 keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()), 167 certificate: key_entry.take_cert(), 168 certificateChain: key_entry.take_cert_chain(), 169 modificationTimeMs: key_entry 170 .metadata() 171 .creation_date() 172 .map(|d| d.to_millis_epoch()) 173 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED)) 174 .context("In get_key_entry: Trying to get creation date.")?, 175 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()), 176 }, 177 }) 178 } 179 update_subcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> Result<()>180 fn update_subcomponent( 181 &self, 182 key: &KeyDescriptor, 183 public_cert: Option<&[u8]>, 184 certificate_chain: Option<&[u8]>, 185 ) -> Result<()> { 186 let caller_uid = ThreadState::get_calling_uid(); 187 DB.with::<_, Result<()>>(|db| { 188 let entry = match LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || { 189 db.borrow_mut().load_key_entry( 190 &key, 191 KeyType::Client, 192 KeyEntryLoadBits::NONE, 193 caller_uid, 194 |k, av| { 195 check_key_permission(KeyPerm::update(), k, &av) 196 .context("In update_subcomponent.") 197 }, 198 ) 199 }) { 200 Err(e) => match e.root_cause().downcast_ref::<Error>() { 201 Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None), 202 _ => Err(e), 203 }, 204 Ok(v) => Ok(Some(v)), 205 } 206 .context("Failed to load key entry.")?; 207 208 let mut db = db.borrow_mut(); 209 if let Some((key_id_guard, _key_entry)) = entry { 210 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None) 211 .context("Failed to update cert subcomponent.")?; 212 213 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None) 214 .context("Failed to update cert chain subcomponent.")?; 215 return Ok(()); 216 } 217 218 // If we reach this point we have to check the special condition where a certificate 219 // entry may be made. 220 if !(public_cert.is_none() && certificate_chain.is_some()) { 221 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)).context("No key to update."); 222 } 223 224 // So we know that we have a certificate chain and no public cert. 225 // Now check that we have everything we need to make a new certificate entry. 226 let key = match (key.domain, &key.alias) { 227 (Domain::APP, Some(ref alias)) => KeyDescriptor { 228 domain: Domain::APP, 229 nspace: ThreadState::get_calling_uid() as i64, 230 alias: Some(alias.clone()), 231 blob: None, 232 }, 233 (Domain::SELINUX, Some(_)) => key.clone(), 234 _ => { 235 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 236 .context("Domain must be APP or SELINUX to insert a certificate.") 237 } 238 }; 239 240 // Security critical: This must return on failure. Do not remove the `?`; 241 check_key_permission(KeyPerm::rebind(), &key, &None) 242 .context("Caller does not have permission to insert this certificate.")?; 243 244 db.store_new_certificate( 245 &key, 246 KeyType::Client, 247 certificate_chain.unwrap(), 248 &KEYSTORE_UUID, 249 ) 250 .context("Failed to insert new certificate.")?; 251 Ok(()) 252 }) 253 .context("In update_subcomponent.") 254 } 255 list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>>256 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> { 257 let mut k = match domain { 258 Domain::APP => KeyDescriptor { 259 domain, 260 nspace: ThreadState::get_calling_uid() as u64 as i64, 261 ..Default::default() 262 }, 263 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()}, 264 _ => return Err(Error::perm()).context( 265 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX." 266 ), 267 }; 268 269 // First we check if the caller has the info permission for the selected domain/namespace. 270 // By default we use the calling uid as namespace if domain is Domain::APP. 271 // If the first check fails we check if the caller has the list permission allowing to list 272 // any namespace. In that case we also adjust the queried namespace if a specific uid was 273 // selected. 274 match check_key_permission(KeyPerm::get_info(), &k, &None) { 275 Err(e) => { 276 if let Some(selinux::Error::PermissionDenied) = 277 e.root_cause().downcast_ref::<selinux::Error>() 278 { 279 check_keystore_permission(KeystorePerm::list()) 280 .context("In list_entries: While checking keystore permission.")?; 281 if namespace != -1 { 282 k.nspace = namespace; 283 } 284 } else { 285 return Err(e).context("In list_entries: While checking key permission.")?; 286 } 287 } 288 Ok(()) => {} 289 }; 290 291 let mut result = LEGACY_MIGRATOR 292 .list_uid(k.domain, k.nspace) 293 .context("In list_entries: Trying to list legacy keys.")?; 294 295 result.append( 296 &mut DB 297 .with(|db| { 298 let mut db = db.borrow_mut(); 299 db.list(k.domain, k.nspace, KeyType::Client) 300 }) 301 .context("In list_entries: Trying to list keystore database.")?, 302 ); 303 304 result.sort_unstable(); 305 result.dedup(); 306 Ok(result) 307 } 308 delete_key(&self, key: &KeyDescriptor) -> Result<()>309 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> { 310 let caller_uid = ThreadState::get_calling_uid(); 311 DB.with(|db| { 312 LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || { 313 db.borrow_mut().unbind_key(&key, KeyType::Client, caller_uid, |k, av| { 314 check_key_permission(KeyPerm::delete(), k, &av).context("During delete_key.") 315 }) 316 }) 317 }) 318 .context("In delete_key: Trying to unbind the key.")?; 319 Ok(()) 320 } 321 grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: permission::KeyPermSet, ) -> Result<KeyDescriptor>322 fn grant( 323 &self, 324 key: &KeyDescriptor, 325 grantee_uid: i32, 326 access_vector: permission::KeyPermSet, 327 ) -> Result<KeyDescriptor> { 328 let caller_uid = ThreadState::get_calling_uid(); 329 DB.with(|db| { 330 LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || { 331 db.borrow_mut().grant( 332 &key, 333 caller_uid, 334 grantee_uid as u32, 335 access_vector, 336 |k, av| check_grant_permission(*av, k).context("During grant."), 337 ) 338 }) 339 }) 340 .context("In KeystoreService::grant.") 341 } 342 ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()>343 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> { 344 DB.with(|db| { 345 db.borrow_mut().ungrant(&key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| { 346 check_key_permission(KeyPerm::grant(), k, &None) 347 }) 348 }) 349 .context("In KeystoreService::ungrant.") 350 } 351 } 352 353 impl binder::Interface for KeystoreService {} 354 355 // Implementation of IKeystoreService. See AIDL spec at 356 // system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl 357 impl IKeystoreService for KeystoreService { getSecurityLevel( &self, security_level: SecurityLevel, ) -> binder::public_api::Result<Strong<dyn IKeystoreSecurityLevel>>358 fn getSecurityLevel( 359 &self, 360 security_level: SecurityLevel, 361 ) -> binder::public_api::Result<Strong<dyn IKeystoreSecurityLevel>> { 362 let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, move || { 363 format!("security_level: {}", security_level.0) 364 }); 365 map_or_log_err(self.get_security_level(security_level), Ok) 366 } getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse>367 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> { 368 let _wp = wd::watch_millis("IKeystoreService::get_key_entry", 500); 369 map_or_log_err(self.get_key_entry(key), Ok) 370 } updateSubcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> binder::public_api::Result<()>371 fn updateSubcomponent( 372 &self, 373 key: &KeyDescriptor, 374 public_cert: Option<&[u8]>, 375 certificate_chain: Option<&[u8]>, 376 ) -> binder::public_api::Result<()> { 377 let _wp = wd::watch_millis("IKeystoreService::updateSubcomponent", 500); 378 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok) 379 } listEntries( &self, domain: Domain, namespace: i64, ) -> binder::public_api::Result<Vec<KeyDescriptor>>380 fn listEntries( 381 &self, 382 domain: Domain, 383 namespace: i64, 384 ) -> binder::public_api::Result<Vec<KeyDescriptor>> { 385 let _wp = wd::watch_millis("IKeystoreService::listEntries", 500); 386 map_or_log_err(self.list_entries(domain, namespace), Ok) 387 } deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()>388 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> { 389 let _wp = wd::watch_millis("IKeystoreService::deleteKey", 500); 390 let result = self.delete_key(key); 391 log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok()); 392 map_or_log_err(result, Ok) 393 } grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: i32, ) -> binder::public_api::Result<KeyDescriptor>394 fn grant( 395 &self, 396 key: &KeyDescriptor, 397 grantee_uid: i32, 398 access_vector: i32, 399 ) -> binder::public_api::Result<KeyDescriptor> { 400 let _wp = wd::watch_millis("IKeystoreService::grant", 500); 401 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok) 402 } ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()>403 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> { 404 let _wp = wd::watch_millis("IKeystoreService::ungrant", 500); 405 map_or_log_err(self.ungrant(key, grantee_uid), Ok) 406 } 407 } 408