1*e1997b9aSAndroid Build Coastguard Worker // Copyright 2020, The Android Open Source Project 2*e1997b9aSAndroid Build Coastguard Worker // 3*e1997b9aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*e1997b9aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*e1997b9aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*e1997b9aSAndroid Build Coastguard Worker // 7*e1997b9aSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*e1997b9aSAndroid Build Coastguard Worker // 9*e1997b9aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*e1997b9aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*e1997b9aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e1997b9aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*e1997b9aSAndroid Build Coastguard Worker // limitations under the License. 14*e1997b9aSAndroid Build Coastguard Worker 15*e1997b9aSAndroid Build Coastguard Worker //! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0 16*e1997b9aSAndroid Build Coastguard Worker //! AIDL spec. 17*e1997b9aSAndroid Build Coastguard Worker 18*e1997b9aSAndroid Build Coastguard Worker use std::collections::HashMap; 19*e1997b9aSAndroid Build Coastguard Worker 20*e1997b9aSAndroid Build Coastguard Worker use crate::audit_log::log_key_deleted; 21*e1997b9aSAndroid Build Coastguard Worker use crate::ks_err; 22*e1997b9aSAndroid Build Coastguard Worker use crate::permission::{KeyPerm, KeystorePerm}; 23*e1997b9aSAndroid Build Coastguard Worker use crate::security_level::KeystoreSecurityLevel; 24*e1997b9aSAndroid Build Coastguard Worker use crate::utils::{ 25*e1997b9aSAndroid Build Coastguard Worker check_grant_permission, check_key_permission, check_keystore_permission, count_key_entries, 26*e1997b9aSAndroid Build Coastguard Worker key_parameters_to_authorizations, list_key_entries, uid_to_android_user, watchdog as wd, 27*e1997b9aSAndroid Build Coastguard Worker }; 28*e1997b9aSAndroid Build Coastguard Worker use crate::{ 29*e1997b9aSAndroid Build Coastguard Worker database::Uuid, 30*e1997b9aSAndroid Build Coastguard Worker globals::{ 31*e1997b9aSAndroid Build Coastguard Worker create_thread_local_db, DB, ENCODED_MODULE_INFO, LEGACY_BLOB_LOADER, LEGACY_IMPORTER, 32*e1997b9aSAndroid Build Coastguard Worker SUPER_KEY, 33*e1997b9aSAndroid Build Coastguard Worker }, 34*e1997b9aSAndroid Build Coastguard Worker }; 35*e1997b9aSAndroid Build Coastguard Worker use crate::{database::KEYSTORE_UUID, permission}; 36*e1997b9aSAndroid Build Coastguard Worker use crate::{ 37*e1997b9aSAndroid Build Coastguard Worker database::{KeyEntryLoadBits, KeyType, SubComponentType}, 38*e1997b9aSAndroid Build Coastguard Worker error::ResponseCode, 39*e1997b9aSAndroid Build Coastguard Worker }; 40*e1997b9aSAndroid Build Coastguard Worker use crate::{ 41*e1997b9aSAndroid Build Coastguard Worker error::{self, into_logged_binder, ErrorCode}, 42*e1997b9aSAndroid Build Coastguard Worker id_rotation::IdRotationState, 43*e1997b9aSAndroid Build Coastguard Worker }; 44*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel; 45*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::aidl::android::hardware::security::keymint::Tag::Tag; 46*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState}; 47*e1997b9aSAndroid Build Coastguard Worker use android_system_keystore2::aidl::android::system::keystore2::{ 48*e1997b9aSAndroid Build Coastguard Worker Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, 49*e1997b9aSAndroid Build Coastguard Worker IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService, 50*e1997b9aSAndroid Build Coastguard Worker KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata, 51*e1997b9aSAndroid Build Coastguard Worker }; 52*e1997b9aSAndroid Build Coastguard Worker use anyhow::{Context, Result}; 53*e1997b9aSAndroid Build Coastguard Worker use error::Error; 54*e1997b9aSAndroid Build Coastguard Worker use keystore2_selinux as selinux; 55*e1997b9aSAndroid Build Coastguard Worker 56*e1997b9aSAndroid Build Coastguard Worker /// Implementation of the IKeystoreService. 57*e1997b9aSAndroid Build Coastguard Worker #[derive(Default)] 58*e1997b9aSAndroid Build Coastguard Worker pub struct KeystoreService { 59*e1997b9aSAndroid Build Coastguard Worker i_sec_level_by_uuid: HashMap<Uuid, Strong<dyn IKeystoreSecurityLevel>>, 60*e1997b9aSAndroid Build Coastguard Worker uuid_by_sec_level: HashMap<SecurityLevel, Uuid>, 61*e1997b9aSAndroid Build Coastguard Worker } 62*e1997b9aSAndroid Build Coastguard Worker 63*e1997b9aSAndroid Build Coastguard Worker impl KeystoreService { 64*e1997b9aSAndroid Build Coastguard Worker /// Create a new instance of the Keystore 2.0 service. new_native_binder( id_rotation_state: IdRotationState, ) -> Result<Strong<dyn IKeystoreService>>65*e1997b9aSAndroid Build Coastguard Worker pub fn new_native_binder( 66*e1997b9aSAndroid Build Coastguard Worker id_rotation_state: IdRotationState, 67*e1997b9aSAndroid Build Coastguard Worker ) -> Result<Strong<dyn IKeystoreService>> { 68*e1997b9aSAndroid Build Coastguard Worker let mut result: Self = Default::default(); 69*e1997b9aSAndroid Build Coastguard Worker let (dev, uuid) = match KeystoreSecurityLevel::new_native_binder( 70*e1997b9aSAndroid Build Coastguard Worker SecurityLevel::TRUSTED_ENVIRONMENT, 71*e1997b9aSAndroid Build Coastguard Worker id_rotation_state.clone(), 72*e1997b9aSAndroid Build Coastguard Worker ) { 73*e1997b9aSAndroid Build Coastguard Worker Ok(v) => v, 74*e1997b9aSAndroid Build Coastguard Worker Err(e) => { 75*e1997b9aSAndroid Build Coastguard Worker log::error!("Failed to construct mandatory security level TEE: {e:?}"); 76*e1997b9aSAndroid Build Coastguard Worker log::error!("Does the device have a /default Keymaster or KeyMint instance?"); 77*e1997b9aSAndroid Build Coastguard Worker return Err(e.context(ks_err!("Trying to construct mandatory security level TEE"))); 78*e1997b9aSAndroid Build Coastguard Worker } 79*e1997b9aSAndroid Build Coastguard Worker }; 80*e1997b9aSAndroid Build Coastguard Worker 81*e1997b9aSAndroid Build Coastguard Worker result.i_sec_level_by_uuid.insert(uuid, dev); 82*e1997b9aSAndroid Build Coastguard Worker result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid); 83*e1997b9aSAndroid Build Coastguard Worker 84*e1997b9aSAndroid Build Coastguard Worker // Strongbox is optional, so we ignore errors and turn the result into an Option. 85*e1997b9aSAndroid Build Coastguard Worker if let Ok((dev, uuid)) = 86*e1997b9aSAndroid Build Coastguard Worker KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state) 87*e1997b9aSAndroid Build Coastguard Worker { 88*e1997b9aSAndroid Build Coastguard Worker result.i_sec_level_by_uuid.insert(uuid, dev); 89*e1997b9aSAndroid Build Coastguard Worker result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid); 90*e1997b9aSAndroid Build Coastguard Worker } 91*e1997b9aSAndroid Build Coastguard Worker 92*e1997b9aSAndroid Build Coastguard Worker let uuid_by_sec_level = result.uuid_by_sec_level.clone(); 93*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER 94*e1997b9aSAndroid Build Coastguard Worker .set_init(move || { 95*e1997b9aSAndroid Build Coastguard Worker (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone()) 96*e1997b9aSAndroid Build Coastguard Worker }) 97*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to initialize the legacy migrator."))?; 98*e1997b9aSAndroid Build Coastguard Worker 99*e1997b9aSAndroid Build Coastguard Worker Ok(BnKeystoreService::new_binder( 100*e1997b9aSAndroid Build Coastguard Worker result, 101*e1997b9aSAndroid Build Coastguard Worker BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() }, 102*e1997b9aSAndroid Build Coastguard Worker )) 103*e1997b9aSAndroid Build Coastguard Worker } 104*e1997b9aSAndroid Build Coastguard Worker uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel105*e1997b9aSAndroid Build Coastguard Worker fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel { 106*e1997b9aSAndroid Build Coastguard Worker self.uuid_by_sec_level 107*e1997b9aSAndroid Build Coastguard Worker .iter() 108*e1997b9aSAndroid Build Coastguard Worker .find(|(_, v)| **v == *uuid) 109*e1997b9aSAndroid Build Coastguard Worker .map(|(s, _)| *s) 110*e1997b9aSAndroid Build Coastguard Worker .unwrap_or(SecurityLevel::SOFTWARE) 111*e1997b9aSAndroid Build Coastguard Worker } 112*e1997b9aSAndroid Build Coastguard Worker get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>>113*e1997b9aSAndroid Build Coastguard Worker fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> { 114*e1997b9aSAndroid Build Coastguard Worker if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) { 115*e1997b9aSAndroid Build Coastguard Worker Ok(dev.clone()) 116*e1997b9aSAndroid Build Coastguard Worker } else { 117*e1997b9aSAndroid Build Coastguard Worker Err(error::Error::sys()).context(ks_err!("KeyMint instance for key not found.")) 118*e1997b9aSAndroid Build Coastguard Worker } 119*e1997b9aSAndroid Build Coastguard Worker } 120*e1997b9aSAndroid Build Coastguard Worker get_security_level( &self, sec_level: SecurityLevel, ) -> Result<Strong<dyn IKeystoreSecurityLevel>>121*e1997b9aSAndroid Build Coastguard Worker fn get_security_level( 122*e1997b9aSAndroid Build Coastguard Worker &self, 123*e1997b9aSAndroid Build Coastguard Worker sec_level: SecurityLevel, 124*e1997b9aSAndroid Build Coastguard Worker ) -> Result<Strong<dyn IKeystoreSecurityLevel>> { 125*e1997b9aSAndroid Build Coastguard Worker if let Some(dev) = self 126*e1997b9aSAndroid Build Coastguard Worker .uuid_by_sec_level 127*e1997b9aSAndroid Build Coastguard Worker .get(&sec_level) 128*e1997b9aSAndroid Build Coastguard Worker .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid)) 129*e1997b9aSAndroid Build Coastguard Worker { 130*e1997b9aSAndroid Build Coastguard Worker Ok(dev.clone()) 131*e1997b9aSAndroid Build Coastguard Worker } else { 132*e1997b9aSAndroid Build Coastguard Worker Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) 133*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("No such security level.")) 134*e1997b9aSAndroid Build Coastguard Worker } 135*e1997b9aSAndroid Build Coastguard Worker } 136*e1997b9aSAndroid Build Coastguard Worker get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse>137*e1997b9aSAndroid Build Coastguard Worker fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> { 138*e1997b9aSAndroid Build Coastguard Worker let caller_uid = ThreadState::get_calling_uid(); 139*e1997b9aSAndroid Build Coastguard Worker 140*e1997b9aSAndroid Build Coastguard Worker let super_key = SUPER_KEY 141*e1997b9aSAndroid Build Coastguard Worker .read() 142*e1997b9aSAndroid Build Coastguard Worker .unwrap() 143*e1997b9aSAndroid Build Coastguard Worker .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid)); 144*e1997b9aSAndroid Build Coastguard Worker 145*e1997b9aSAndroid Build Coastguard Worker let (key_id_guard, mut key_entry) = DB 146*e1997b9aSAndroid Build Coastguard Worker .with(|db| { 147*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || { 148*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().load_key_entry( 149*e1997b9aSAndroid Build Coastguard Worker key, 150*e1997b9aSAndroid Build Coastguard Worker KeyType::Client, 151*e1997b9aSAndroid Build Coastguard Worker KeyEntryLoadBits::PUBLIC, 152*e1997b9aSAndroid Build Coastguard Worker caller_uid, 153*e1997b9aSAndroid Build Coastguard Worker |k, av| check_key_permission(KeyPerm::GetInfo, k, &av), 154*e1997b9aSAndroid Build Coastguard Worker ) 155*e1997b9aSAndroid Build Coastguard Worker }) 156*e1997b9aSAndroid Build Coastguard Worker }) 157*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("while trying to load key info."))?; 158*e1997b9aSAndroid Build Coastguard Worker 159*e1997b9aSAndroid Build Coastguard Worker let i_sec_level = if !key_entry.pure_cert() { 160*e1997b9aSAndroid Build Coastguard Worker Some( 161*e1997b9aSAndroid Build Coastguard Worker self.get_i_sec_level_by_uuid(key_entry.km_uuid()) 162*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to get security level proxy."))?, 163*e1997b9aSAndroid Build Coastguard Worker ) 164*e1997b9aSAndroid Build Coastguard Worker } else { 165*e1997b9aSAndroid Build Coastguard Worker None 166*e1997b9aSAndroid Build Coastguard Worker }; 167*e1997b9aSAndroid Build Coastguard Worker 168*e1997b9aSAndroid Build Coastguard Worker Ok(KeyEntryResponse { 169*e1997b9aSAndroid Build Coastguard Worker iSecurityLevel: i_sec_level, 170*e1997b9aSAndroid Build Coastguard Worker metadata: KeyMetadata { 171*e1997b9aSAndroid Build Coastguard Worker key: KeyDescriptor { 172*e1997b9aSAndroid Build Coastguard Worker domain: Domain::KEY_ID, 173*e1997b9aSAndroid Build Coastguard Worker nspace: key_id_guard.id(), 174*e1997b9aSAndroid Build Coastguard Worker ..Default::default() 175*e1997b9aSAndroid Build Coastguard Worker }, 176*e1997b9aSAndroid Build Coastguard Worker keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()), 177*e1997b9aSAndroid Build Coastguard Worker certificate: key_entry.take_cert(), 178*e1997b9aSAndroid Build Coastguard Worker certificateChain: key_entry.take_cert_chain(), 179*e1997b9aSAndroid Build Coastguard Worker modificationTimeMs: key_entry 180*e1997b9aSAndroid Build Coastguard Worker .metadata() 181*e1997b9aSAndroid Build Coastguard Worker .creation_date() 182*e1997b9aSAndroid Build Coastguard Worker .map(|d| d.to_millis_epoch()) 183*e1997b9aSAndroid Build Coastguard Worker .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED)) 184*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to get creation date."))?, 185*e1997b9aSAndroid Build Coastguard Worker authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()), 186*e1997b9aSAndroid Build Coastguard Worker }, 187*e1997b9aSAndroid Build Coastguard Worker }) 188*e1997b9aSAndroid Build Coastguard Worker } 189*e1997b9aSAndroid Build Coastguard Worker update_subcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> Result<()>190*e1997b9aSAndroid Build Coastguard Worker fn update_subcomponent( 191*e1997b9aSAndroid Build Coastguard Worker &self, 192*e1997b9aSAndroid Build Coastguard Worker key: &KeyDescriptor, 193*e1997b9aSAndroid Build Coastguard Worker public_cert: Option<&[u8]>, 194*e1997b9aSAndroid Build Coastguard Worker certificate_chain: Option<&[u8]>, 195*e1997b9aSAndroid Build Coastguard Worker ) -> Result<()> { 196*e1997b9aSAndroid Build Coastguard Worker let caller_uid = ThreadState::get_calling_uid(); 197*e1997b9aSAndroid Build Coastguard Worker let super_key = SUPER_KEY 198*e1997b9aSAndroid Build Coastguard Worker .read() 199*e1997b9aSAndroid Build Coastguard Worker .unwrap() 200*e1997b9aSAndroid Build Coastguard Worker .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid)); 201*e1997b9aSAndroid Build Coastguard Worker 202*e1997b9aSAndroid Build Coastguard Worker DB.with::<_, Result<()>>(|db| { 203*e1997b9aSAndroid Build Coastguard Worker let entry = match LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || { 204*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().load_key_entry( 205*e1997b9aSAndroid Build Coastguard Worker key, 206*e1997b9aSAndroid Build Coastguard Worker KeyType::Client, 207*e1997b9aSAndroid Build Coastguard Worker KeyEntryLoadBits::NONE, 208*e1997b9aSAndroid Build Coastguard Worker caller_uid, 209*e1997b9aSAndroid Build Coastguard Worker |k, av| check_key_permission(KeyPerm::Update, k, &av).context(ks_err!()), 210*e1997b9aSAndroid Build Coastguard Worker ) 211*e1997b9aSAndroid Build Coastguard Worker }) { 212*e1997b9aSAndroid Build Coastguard Worker Err(e) => match e.root_cause().downcast_ref::<Error>() { 213*e1997b9aSAndroid Build Coastguard Worker Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None), 214*e1997b9aSAndroid Build Coastguard Worker _ => Err(e), 215*e1997b9aSAndroid Build Coastguard Worker }, 216*e1997b9aSAndroid Build Coastguard Worker Ok(v) => Ok(Some(v)), 217*e1997b9aSAndroid Build Coastguard Worker } 218*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to load key entry."))?; 219*e1997b9aSAndroid Build Coastguard Worker 220*e1997b9aSAndroid Build Coastguard Worker let mut db = db.borrow_mut(); 221*e1997b9aSAndroid Build Coastguard Worker if let Some((key_id_guard, _key_entry)) = entry { 222*e1997b9aSAndroid Build Coastguard Worker db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None) 223*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to update cert subcomponent."))?; 224*e1997b9aSAndroid Build Coastguard Worker 225*e1997b9aSAndroid Build Coastguard Worker db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None) 226*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to update cert chain subcomponent."))?; 227*e1997b9aSAndroid Build Coastguard Worker return Ok(()); 228*e1997b9aSAndroid Build Coastguard Worker } 229*e1997b9aSAndroid Build Coastguard Worker 230*e1997b9aSAndroid Build Coastguard Worker // If we reach this point we have to check the special condition where a certificate 231*e1997b9aSAndroid Build Coastguard Worker // entry may be made. 232*e1997b9aSAndroid Build Coastguard Worker if !(public_cert.is_none() && certificate_chain.is_some()) { 233*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)) 234*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("No key to update.")); 235*e1997b9aSAndroid Build Coastguard Worker } 236*e1997b9aSAndroid Build Coastguard Worker 237*e1997b9aSAndroid Build Coastguard Worker // So we know that we have a certificate chain and no public cert. 238*e1997b9aSAndroid Build Coastguard Worker // Now check that we have everything we need to make a new certificate entry. 239*e1997b9aSAndroid Build Coastguard Worker let key = match (key.domain, &key.alias) { 240*e1997b9aSAndroid Build Coastguard Worker (Domain::APP, Some(ref alias)) => KeyDescriptor { 241*e1997b9aSAndroid Build Coastguard Worker domain: Domain::APP, 242*e1997b9aSAndroid Build Coastguard Worker nspace: ThreadState::get_calling_uid() as i64, 243*e1997b9aSAndroid Build Coastguard Worker alias: Some(alias.clone()), 244*e1997b9aSAndroid Build Coastguard Worker blob: None, 245*e1997b9aSAndroid Build Coastguard Worker }, 246*e1997b9aSAndroid Build Coastguard Worker (Domain::SELINUX, Some(_)) => key.clone(), 247*e1997b9aSAndroid Build Coastguard Worker _ => { 248*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 249*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Domain must be APP or SELINUX to insert a certificate.")) 250*e1997b9aSAndroid Build Coastguard Worker } 251*e1997b9aSAndroid Build Coastguard Worker }; 252*e1997b9aSAndroid Build Coastguard Worker 253*e1997b9aSAndroid Build Coastguard Worker // Security critical: This must return on failure. Do not remove the `?`; 254*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Rebind, &key, &None) 255*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Caller does not have permission to insert this certificate."))?; 256*e1997b9aSAndroid Build Coastguard Worker 257*e1997b9aSAndroid Build Coastguard Worker db.store_new_certificate( 258*e1997b9aSAndroid Build Coastguard Worker &key, 259*e1997b9aSAndroid Build Coastguard Worker KeyType::Client, 260*e1997b9aSAndroid Build Coastguard Worker certificate_chain.unwrap(), 261*e1997b9aSAndroid Build Coastguard Worker &KEYSTORE_UUID, 262*e1997b9aSAndroid Build Coastguard Worker ) 263*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to insert new certificate."))?; 264*e1997b9aSAndroid Build Coastguard Worker Ok(()) 265*e1997b9aSAndroid Build Coastguard Worker }) 266*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!()) 267*e1997b9aSAndroid Build Coastguard Worker } 268*e1997b9aSAndroid Build Coastguard Worker get_key_descriptor_for_lookup( &self, domain: Domain, namespace: i64, ) -> Result<KeyDescriptor>269*e1997b9aSAndroid Build Coastguard Worker fn get_key_descriptor_for_lookup( 270*e1997b9aSAndroid Build Coastguard Worker &self, 271*e1997b9aSAndroid Build Coastguard Worker domain: Domain, 272*e1997b9aSAndroid Build Coastguard Worker namespace: i64, 273*e1997b9aSAndroid Build Coastguard Worker ) -> Result<KeyDescriptor> { 274*e1997b9aSAndroid Build Coastguard Worker let mut k = match domain { 275*e1997b9aSAndroid Build Coastguard Worker Domain::APP => KeyDescriptor { 276*e1997b9aSAndroid Build Coastguard Worker domain, 277*e1997b9aSAndroid Build Coastguard Worker nspace: ThreadState::get_calling_uid() as u64 as i64, 278*e1997b9aSAndroid Build Coastguard Worker ..Default::default() 279*e1997b9aSAndroid Build Coastguard Worker }, 280*e1997b9aSAndroid Build Coastguard Worker Domain::SELINUX => KeyDescriptor { domain, nspace: namespace, ..Default::default() }, 281*e1997b9aSAndroid Build Coastguard Worker _ => { 282*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!( 283*e1997b9aSAndroid Build Coastguard Worker "List entries is only supported for Domain::APP and Domain::SELINUX." 284*e1997b9aSAndroid Build Coastguard Worker )) 285*e1997b9aSAndroid Build Coastguard Worker } 286*e1997b9aSAndroid Build Coastguard Worker }; 287*e1997b9aSAndroid Build Coastguard Worker 288*e1997b9aSAndroid Build Coastguard Worker // First we check if the caller has the info permission for the selected domain/namespace. 289*e1997b9aSAndroid Build Coastguard Worker // By default we use the calling uid as namespace if domain is Domain::APP. 290*e1997b9aSAndroid Build Coastguard Worker // If the first check fails we check if the caller has the list permission allowing to list 291*e1997b9aSAndroid Build Coastguard Worker // any namespace. In that case we also adjust the queried namespace if a specific uid was 292*e1997b9aSAndroid Build Coastguard Worker // selected. 293*e1997b9aSAndroid Build Coastguard Worker if let Err(e) = check_key_permission(KeyPerm::GetInfo, &k, &None) { 294*e1997b9aSAndroid Build Coastguard Worker if let Some(selinux::Error::PermissionDenied) = 295*e1997b9aSAndroid Build Coastguard Worker e.root_cause().downcast_ref::<selinux::Error>() 296*e1997b9aSAndroid Build Coastguard Worker { 297*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::List) 298*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("While checking keystore permission."))?; 299*e1997b9aSAndroid Build Coastguard Worker if namespace != -1 { 300*e1997b9aSAndroid Build Coastguard Worker k.nspace = namespace; 301*e1997b9aSAndroid Build Coastguard Worker } 302*e1997b9aSAndroid Build Coastguard Worker } else { 303*e1997b9aSAndroid Build Coastguard Worker return Err(e).context(ks_err!("While checking key permission."))?; 304*e1997b9aSAndroid Build Coastguard Worker } 305*e1997b9aSAndroid Build Coastguard Worker } 306*e1997b9aSAndroid Build Coastguard Worker Ok(k) 307*e1997b9aSAndroid Build Coastguard Worker } 308*e1997b9aSAndroid Build Coastguard Worker list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>>309*e1997b9aSAndroid Build Coastguard Worker fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> { 310*e1997b9aSAndroid Build Coastguard Worker let k = self.get_key_descriptor_for_lookup(domain, namespace)?; 311*e1997b9aSAndroid Build Coastguard Worker 312*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace, None)) 313*e1997b9aSAndroid Build Coastguard Worker } 314*e1997b9aSAndroid Build Coastguard Worker count_num_entries(&self, domain: Domain, namespace: i64) -> Result<i32>315*e1997b9aSAndroid Build Coastguard Worker fn count_num_entries(&self, domain: Domain, namespace: i64) -> Result<i32> { 316*e1997b9aSAndroid Build Coastguard Worker let k = self.get_key_descriptor_for_lookup(domain, namespace)?; 317*e1997b9aSAndroid Build Coastguard Worker 318*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| count_key_entries(&mut db.borrow_mut(), k.domain, k.nspace)) 319*e1997b9aSAndroid Build Coastguard Worker } 320*e1997b9aSAndroid Build Coastguard Worker get_supplementary_attestation_info(&self, tag: Tag) -> Result<Vec<u8>>321*e1997b9aSAndroid Build Coastguard Worker fn get_supplementary_attestation_info(&self, tag: Tag) -> Result<Vec<u8>> { 322*e1997b9aSAndroid Build Coastguard Worker match tag { 323*e1997b9aSAndroid Build Coastguard Worker Tag::MODULE_HASH => { 324*e1997b9aSAndroid Build Coastguard Worker let info = ENCODED_MODULE_INFO.read().unwrap(); 325*e1997b9aSAndroid Build Coastguard Worker (*info) 326*e1997b9aSAndroid Build Coastguard Worker .clone() 327*e1997b9aSAndroid Build Coastguard Worker .ok_or(Error::Rc(ResponseCode::INFO_NOT_AVAILABLE)) 328*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Module info not received.")) 329*e1997b9aSAndroid Build Coastguard Worker } 330*e1997b9aSAndroid Build Coastguard Worker _ => Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 331*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Tag {tag:?} not supported for getSupplementaryAttestationInfo.")), 332*e1997b9aSAndroid Build Coastguard Worker } 333*e1997b9aSAndroid Build Coastguard Worker } 334*e1997b9aSAndroid Build Coastguard Worker list_entries_batched( &self, domain: Domain, namespace: i64, start_past_alias: Option<&str>, ) -> Result<Vec<KeyDescriptor>>335*e1997b9aSAndroid Build Coastguard Worker fn list_entries_batched( 336*e1997b9aSAndroid Build Coastguard Worker &self, 337*e1997b9aSAndroid Build Coastguard Worker domain: Domain, 338*e1997b9aSAndroid Build Coastguard Worker namespace: i64, 339*e1997b9aSAndroid Build Coastguard Worker start_past_alias: Option<&str>, 340*e1997b9aSAndroid Build Coastguard Worker ) -> Result<Vec<KeyDescriptor>> { 341*e1997b9aSAndroid Build Coastguard Worker let k = self.get_key_descriptor_for_lookup(domain, namespace)?; 342*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace, start_past_alias)) 343*e1997b9aSAndroid Build Coastguard Worker } 344*e1997b9aSAndroid Build Coastguard Worker delete_key(&self, key: &KeyDescriptor) -> Result<()>345*e1997b9aSAndroid Build Coastguard Worker fn delete_key(&self, key: &KeyDescriptor) -> Result<()> { 346*e1997b9aSAndroid Build Coastguard Worker let caller_uid = ThreadState::get_calling_uid(); 347*e1997b9aSAndroid Build Coastguard Worker let super_key = SUPER_KEY 348*e1997b9aSAndroid Build Coastguard Worker .read() 349*e1997b9aSAndroid Build Coastguard Worker .unwrap() 350*e1997b9aSAndroid Build Coastguard Worker .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid)); 351*e1997b9aSAndroid Build Coastguard Worker 352*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 353*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || { 354*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().unbind_key(key, KeyType::Client, caller_uid, |k, av| { 355*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Delete, k, &av) 356*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("During delete_key.")) 357*e1997b9aSAndroid Build Coastguard Worker }) 358*e1997b9aSAndroid Build Coastguard Worker }) 359*e1997b9aSAndroid Build Coastguard Worker }) 360*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to unbind the key."))?; 361*e1997b9aSAndroid Build Coastguard Worker Ok(()) 362*e1997b9aSAndroid Build Coastguard Worker } 363*e1997b9aSAndroid Build Coastguard Worker grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: permission::KeyPermSet, ) -> Result<KeyDescriptor>364*e1997b9aSAndroid Build Coastguard Worker fn grant( 365*e1997b9aSAndroid Build Coastguard Worker &self, 366*e1997b9aSAndroid Build Coastguard Worker key: &KeyDescriptor, 367*e1997b9aSAndroid Build Coastguard Worker grantee_uid: i32, 368*e1997b9aSAndroid Build Coastguard Worker access_vector: permission::KeyPermSet, 369*e1997b9aSAndroid Build Coastguard Worker ) -> Result<KeyDescriptor> { 370*e1997b9aSAndroid Build Coastguard Worker let caller_uid = ThreadState::get_calling_uid(); 371*e1997b9aSAndroid Build Coastguard Worker let super_key = SUPER_KEY 372*e1997b9aSAndroid Build Coastguard Worker .read() 373*e1997b9aSAndroid Build Coastguard Worker .unwrap() 374*e1997b9aSAndroid Build Coastguard Worker .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid)); 375*e1997b9aSAndroid Build Coastguard Worker 376*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 377*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || { 378*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().grant( 379*e1997b9aSAndroid Build Coastguard Worker key, 380*e1997b9aSAndroid Build Coastguard Worker caller_uid, 381*e1997b9aSAndroid Build Coastguard Worker grantee_uid as u32, 382*e1997b9aSAndroid Build Coastguard Worker access_vector, 383*e1997b9aSAndroid Build Coastguard Worker |k, av| check_grant_permission(*av, k).context("During grant."), 384*e1997b9aSAndroid Build Coastguard Worker ) 385*e1997b9aSAndroid Build Coastguard Worker }) 386*e1997b9aSAndroid Build Coastguard Worker }) 387*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("KeystoreService::grant.")) 388*e1997b9aSAndroid Build Coastguard Worker } 389*e1997b9aSAndroid Build Coastguard Worker ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()>390*e1997b9aSAndroid Build Coastguard Worker fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> { 391*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 392*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().ungrant(key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| { 393*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Grant, k, &None) 394*e1997b9aSAndroid Build Coastguard Worker }) 395*e1997b9aSAndroid Build Coastguard Worker }) 396*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("KeystoreService::ungrant.")) 397*e1997b9aSAndroid Build Coastguard Worker } 398*e1997b9aSAndroid Build Coastguard Worker } 399*e1997b9aSAndroid Build Coastguard Worker 400*e1997b9aSAndroid Build Coastguard Worker impl binder::Interface for KeystoreService {} 401*e1997b9aSAndroid Build Coastguard Worker 402*e1997b9aSAndroid Build Coastguard Worker // Implementation of IKeystoreService. See AIDL spec at 403*e1997b9aSAndroid Build Coastguard Worker // system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl 404*e1997b9aSAndroid Build Coastguard Worker impl IKeystoreService for KeystoreService { getSecurityLevel( &self, security_level: SecurityLevel, ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>>405*e1997b9aSAndroid Build Coastguard Worker fn getSecurityLevel( 406*e1997b9aSAndroid Build Coastguard Worker &self, 407*e1997b9aSAndroid Build Coastguard Worker security_level: SecurityLevel, 408*e1997b9aSAndroid Build Coastguard Worker ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>> { 409*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, security_level); 410*e1997b9aSAndroid Build Coastguard Worker self.get_security_level(security_level).map_err(into_logged_binder) 411*e1997b9aSAndroid Build Coastguard Worker } getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse>412*e1997b9aSAndroid Build Coastguard Worker fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse> { 413*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::get_key_entry"); 414*e1997b9aSAndroid Build Coastguard Worker self.get_key_entry(key).map_err(into_logged_binder) 415*e1997b9aSAndroid Build Coastguard Worker } updateSubcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> binder::Result<()>416*e1997b9aSAndroid Build Coastguard Worker fn updateSubcomponent( 417*e1997b9aSAndroid Build Coastguard Worker &self, 418*e1997b9aSAndroid Build Coastguard Worker key: &KeyDescriptor, 419*e1997b9aSAndroid Build Coastguard Worker public_cert: Option<&[u8]>, 420*e1997b9aSAndroid Build Coastguard Worker certificate_chain: Option<&[u8]>, 421*e1997b9aSAndroid Build Coastguard Worker ) -> binder::Result<()> { 422*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::updateSubcomponent"); 423*e1997b9aSAndroid Build Coastguard Worker self.update_subcomponent(key, public_cert, certificate_chain).map_err(into_logged_binder) 424*e1997b9aSAndroid Build Coastguard Worker } listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>>425*e1997b9aSAndroid Build Coastguard Worker fn listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>> { 426*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::listEntries"); 427*e1997b9aSAndroid Build Coastguard Worker self.list_entries(domain, namespace).map_err(into_logged_binder) 428*e1997b9aSAndroid Build Coastguard Worker } deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()>429*e1997b9aSAndroid Build Coastguard Worker fn deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()> { 430*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::deleteKey"); 431*e1997b9aSAndroid Build Coastguard Worker let result = self.delete_key(key); 432*e1997b9aSAndroid Build Coastguard Worker log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok()); 433*e1997b9aSAndroid Build Coastguard Worker result.map_err(into_logged_binder) 434*e1997b9aSAndroid Build Coastguard Worker } grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: i32, ) -> binder::Result<KeyDescriptor>435*e1997b9aSAndroid Build Coastguard Worker fn grant( 436*e1997b9aSAndroid Build Coastguard Worker &self, 437*e1997b9aSAndroid Build Coastguard Worker key: &KeyDescriptor, 438*e1997b9aSAndroid Build Coastguard Worker grantee_uid: i32, 439*e1997b9aSAndroid Build Coastguard Worker access_vector: i32, 440*e1997b9aSAndroid Build Coastguard Worker ) -> binder::Result<KeyDescriptor> { 441*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::grant"); 442*e1997b9aSAndroid Build Coastguard Worker self.grant(key, grantee_uid, access_vector.into()).map_err(into_logged_binder) 443*e1997b9aSAndroid Build Coastguard Worker } ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()>444*e1997b9aSAndroid Build Coastguard Worker fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()> { 445*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::ungrant"); 446*e1997b9aSAndroid Build Coastguard Worker self.ungrant(key, grantee_uid).map_err(into_logged_binder) 447*e1997b9aSAndroid Build Coastguard Worker } listEntriesBatched( &self, domain: Domain, namespace: i64, start_past_alias: Option<&str>, ) -> binder::Result<Vec<KeyDescriptor>>448*e1997b9aSAndroid Build Coastguard Worker fn listEntriesBatched( 449*e1997b9aSAndroid Build Coastguard Worker &self, 450*e1997b9aSAndroid Build Coastguard Worker domain: Domain, 451*e1997b9aSAndroid Build Coastguard Worker namespace: i64, 452*e1997b9aSAndroid Build Coastguard Worker start_past_alias: Option<&str>, 453*e1997b9aSAndroid Build Coastguard Worker ) -> binder::Result<Vec<KeyDescriptor>> { 454*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::listEntriesBatched"); 455*e1997b9aSAndroid Build Coastguard Worker self.list_entries_batched(domain, namespace, start_past_alias).map_err(into_logged_binder) 456*e1997b9aSAndroid Build Coastguard Worker } 457*e1997b9aSAndroid Build Coastguard Worker getNumberOfEntries(&self, domain: Domain, namespace: i64) -> binder::Result<i32>458*e1997b9aSAndroid Build Coastguard Worker fn getNumberOfEntries(&self, domain: Domain, namespace: i64) -> binder::Result<i32> { 459*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::getNumberOfEntries"); 460*e1997b9aSAndroid Build Coastguard Worker self.count_num_entries(domain, namespace).map_err(into_logged_binder) 461*e1997b9aSAndroid Build Coastguard Worker } 462*e1997b9aSAndroid Build Coastguard Worker getSupplementaryAttestationInfo(&self, tag: Tag) -> binder::Result<Vec<u8>>463*e1997b9aSAndroid Build Coastguard Worker fn getSupplementaryAttestationInfo(&self, tag: Tag) -> binder::Result<Vec<u8>> { 464*e1997b9aSAndroid Build Coastguard Worker if keystore2_flags::attest_modules() { 465*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreService::getSupplementaryAttestationInfo"); 466*e1997b9aSAndroid Build Coastguard Worker self.get_supplementary_attestation_info(tag).map_err(into_logged_binder) 467*e1997b9aSAndroid Build Coastguard Worker } else { 468*e1997b9aSAndroid Build Coastguard Worker log::error!("attest_modules flag is not toggled"); 469*e1997b9aSAndroid Build Coastguard Worker Err(binder::StatusCode::UNKNOWN_TRANSACTION.into()) 470*e1997b9aSAndroid Build Coastguard Worker } 471*e1997b9aSAndroid Build Coastguard Worker } 472*e1997b9aSAndroid Build Coastguard Worker } 473