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