blob: 1040228663612e0dfd1ae8a8dec9300250431fcb [file] [log] [blame]
Janis Danisevskis1af91262020-08-10 14:58:08 -07001// 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
Janis Danisevskis1af91262020-08-10 14:58:08 -070015//! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
16//! AIDL spec.
17
Max Bires8e93d2b2021-01-14 13:17:59 -080018use std::collections::HashMap;
19
Pavel Grafov94243c22021-04-21 18:03:11 +010020use crate::audit_log::log_key_deleted;
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +000021use crate::ks_err;
Janis Danisevskise92a5e62020-12-02 12:57:41 -080022use crate::permission::{KeyPerm, KeystorePerm};
Janis Danisevskis1af91262020-08-10 14:58:08 -070023use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070024use crate::utils::{
Janis Danisevskise92a5e62020-12-02 12:57:41 -080025 check_grant_permission, check_key_permission, check_keystore_permission,
Janis Danisevskisf84d0b02022-01-26 14:11:14 -080026 key_parameters_to_authorizations, list_key_entries, uid_to_android_user, watchdog as wd,
Janis Danisevskis04b02832020-10-26 09:21:40 -070027};
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000028use crate::{
29 database::Uuid,
Janis Danisevskisf84d0b02022-01-26 14:11:14 -080030 globals::{create_thread_local_db, DB, LEGACY_BLOB_LOADER, LEGACY_IMPORTER, SUPER_KEY},
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000031};
Max Bires8e93d2b2021-01-14 13:17:59 -080032use crate::{database::KEYSTORE_UUID, permission};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080033use crate::{
34 database::{KeyEntryLoadBits, KeyType, SubComponentType},
35 error::ResponseCode,
36};
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070037use crate::{
38 error::{self, map_or_log_err, ErrorCode},
39 id_rotation::IdRotationState,
40};
Shawn Willden708744a2020-12-11 13:05:27 +000041use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Andrew Walbrande45c8b2021-04-13 14:42:38 +000042use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
Janis Danisevskis1af91262020-08-10 14:58:08 -070043use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070044 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
45 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
46 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070047};
Max Bires8e93d2b2021-01-14 13:17:59 -080048use anyhow::{Context, Result};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080049use error::Error;
50use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070051
52/// Implementation of the IKeystoreService.
Max Bires8e93d2b2021-01-14 13:17:59 -080053#[derive(Default)]
Janis Danisevskis1af91262020-08-10 14:58:08 -070054pub struct KeystoreService {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -070055 i_sec_level_by_uuid: HashMap<Uuid, Strong<dyn IKeystoreSecurityLevel>>,
Max Bires8e93d2b2021-01-14 13:17:59 -080056 uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
Janis Danisevskis1af91262020-08-10 14:58:08 -070057}
58
59impl KeystoreService {
60 /// Create a new instance of the Keystore 2.0 service.
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070061 pub fn new_native_binder(
62 id_rotation_state: IdRotationState,
63 ) -> Result<Strong<dyn IKeystoreService>> {
Max Bires8e93d2b2021-01-14 13:17:59 -080064 let mut result: Self = Default::default();
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070065 let (dev, uuid) = KeystoreSecurityLevel::new_native_binder(
66 SecurityLevel::TRUSTED_ENVIRONMENT,
67 id_rotation_state.clone(),
68 )
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +000069 .context(ks_err!("Trying to construct mandatory security level TEE."))?;
Max Bires8e93d2b2021-01-14 13:17:59 -080070 result.i_sec_level_by_uuid.insert(uuid, dev);
71 result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid);
Janis Danisevskisba998992020-12-29 16:08:40 -080072
Max Bires8e93d2b2021-01-14 13:17:59 -080073 // Strongbox is optional, so we ignore errors and turn the result into an Option.
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070074 if let Ok((dev, uuid)) =
75 KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state)
Max Bires8e93d2b2021-01-14 13:17:59 -080076 {
77 result.i_sec_level_by_uuid.insert(uuid, dev);
78 result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
79 }
80
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000081 let uuid_by_sec_level = result.uuid_by_sec_level.clone();
Janis Danisevskis0ffb8a82022-02-06 22:37:21 -080082 LEGACY_IMPORTER
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000083 .set_init(move || {
84 (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone())
85 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +000086 .context(ks_err!("Trying to initialize the legacy migrator."))?;
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000087
Andrew Walbrande45c8b2021-04-13 14:42:38 +000088 Ok(BnKeystoreService::new_binder(
89 result,
90 BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
91 ))
Janis Danisevskis1af91262020-08-10 14:58:08 -070092 }
93
Max Bires8e93d2b2021-01-14 13:17:59 -080094 fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel {
95 self.uuid_by_sec_level
96 .iter()
97 .find(|(_, v)| **v == *uuid)
98 .map(|(s, _)| *s)
99 .unwrap_or(SecurityLevel::SOFTWARE)
100 }
101
Stephen Crane221bbb52020-12-16 15:52:10 -0800102 fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800103 if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700104 Ok(dev.clone())
Max Bires8e93d2b2021-01-14 13:17:59 -0800105 } else {
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000106 Err(error::Error::sys()).context(ks_err!("KeyMint instance for key not found."))
Max Bires8e93d2b2021-01-14 13:17:59 -0800107 }
Janis Danisevskisba998992020-12-29 16:08:40 -0800108 }
109
Janis Danisevskis1af91262020-08-10 14:58:08 -0700110 fn get_security_level(
111 &self,
Max Bires8e93d2b2021-01-14 13:17:59 -0800112 sec_level: SecurityLevel,
Stephen Crane221bbb52020-12-16 15:52:10 -0800113 ) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800114 if let Some(dev) = self
115 .uuid_by_sec_level
116 .get(&sec_level)
117 .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid))
118 {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700119 Ok(dev.clone())
Max Bires8e93d2b2021-01-14 13:17:59 -0800120 } else {
121 Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000122 .context(ks_err!("No such security level."))
Max Bires8e93d2b2021-01-14 13:17:59 -0800123 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700124 }
125
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700126 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000127 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800128
129 let super_key =
130 SUPER_KEY.read().unwrap().get_per_boot_key_by_user_id(uid_to_android_user(caller_uid));
131
Janis Danisevskisaec14592020-11-12 09:41:49 -0800132 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700133 .with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800134 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000135 db.borrow_mut().load_key_entry(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700136 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000137 KeyType::Client,
138 KeyEntryLoadBits::PUBLIC,
139 caller_uid,
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700140 |k, av| check_key_permission(KeyPerm::GetInfo, k, &av),
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000141 )
142 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700143 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000144 .context(ks_err!("while trying to load key info."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700145
Janis Danisevskis377d1002021-01-27 19:07:48 -0800146 let i_sec_level = if !key_entry.pure_cert() {
147 Some(
Max Bires8e93d2b2021-01-14 13:17:59 -0800148 self.get_i_sec_level_by_uuid(key_entry.km_uuid())
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000149 .context(ks_err!("Trying to get security level proxy."))?,
Janis Danisevskis377d1002021-01-27 19:07:48 -0800150 )
151 } else {
152 None
153 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700154
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700155 Ok(KeyEntryResponse {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800156 iSecurityLevel: i_sec_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700157 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700158 key: KeyDescriptor {
159 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800160 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700161 ..Default::default()
162 },
Max Bires8e93d2b2021-01-14 13:17:59 -0800163 keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700164 certificate: key_entry.take_cert(),
165 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800166 modificationTimeMs: key_entry
167 .metadata()
168 .creation_date()
169 .map(|d| d.to_millis_epoch())
170 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000171 .context(ks_err!("Trying to get creation date."))?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700172 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700173 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700174 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700175 }
176
177 fn update_subcomponent(
178 &self,
179 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700180 public_cert: Option<&[u8]>,
181 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700182 ) -> Result<()> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000183 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800184 let super_key =
185 SUPER_KEY.read().unwrap().get_per_boot_key_by_user_id(uid_to_android_user(caller_uid));
186
Janis Danisevskis1af91262020-08-10 14:58:08 -0700187 DB.with::<_, Result<()>>(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800188 let entry = match LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000189 db.borrow_mut().load_key_entry(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700190 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000191 KeyType::Client,
192 KeyEntryLoadBits::NONE,
193 caller_uid,
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000194 |k, av| check_key_permission(KeyPerm::Update, k, &av).context(ks_err!()),
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000195 )
196 }) {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800197 Err(e) => match e.root_cause().downcast_ref::<Error>() {
198 Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
199 _ => Err(e),
200 },
201 Ok(v) => Ok(Some(v)),
202 }
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000203 .context(ks_err!("Failed to load key entry."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700204
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000205 let mut db = db.borrow_mut();
Paul Crowleyd5653e52021-03-25 09:46:31 -0700206 if let Some((key_id_guard, _key_entry)) = entry {
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800207 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000208 .context(ks_err!("Failed to update cert subcomponent."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800209
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800210 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000211 .context(ks_err!("Failed to update cert chain subcomponent."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800212 return Ok(());
Janis Danisevskis1af91262020-08-10 14:58:08 -0700213 }
214
Janis Danisevskis377d1002021-01-27 19:07:48 -0800215 // If we reach this point we have to check the special condition where a certificate
216 // entry may be made.
217 if !(public_cert.is_none() && certificate_chain.is_some()) {
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000218 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
219 .context(ks_err!("No key to update."));
Janis Danisevskis1af91262020-08-10 14:58:08 -0700220 }
Janis Danisevskis377d1002021-01-27 19:07:48 -0800221
222 // So we know that we have a certificate chain and no public cert.
223 // Now check that we have everything we need to make a new certificate entry.
224 let key = match (key.domain, &key.alias) {
225 (Domain::APP, Some(ref alias)) => KeyDescriptor {
226 domain: Domain::APP,
227 nspace: ThreadState::get_calling_uid() as i64,
228 alias: Some(alias.clone()),
229 blob: None,
230 },
231 (Domain::SELINUX, Some(_)) => key.clone(),
232 _ => {
233 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000234 .context(ks_err!("Domain must be APP or SELINUX to insert a certificate."))
Janis Danisevskis377d1002021-01-27 19:07:48 -0800235 }
236 };
237
238 // Security critical: This must return on failure. Do not remove the `?`;
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700239 check_key_permission(KeyPerm::Rebind, &key, &None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000240 .context(ks_err!("Caller does not have permission to insert this certificate."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800241
Janis Danisevskis0cabd712021-05-25 11:07:10 -0700242 db.store_new_certificate(
243 &key,
244 KeyType::Client,
245 certificate_chain.unwrap(),
246 &KEYSTORE_UUID,
247 )
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000248 .context(ks_err!("Failed to insert new certificate."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700249 Ok(())
250 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000251 .context(ks_err!())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700252 }
253
254 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800255 let mut k = match domain {
256 Domain::APP => KeyDescriptor {
257 domain,
258 nspace: ThreadState::get_calling_uid() as u64 as i64,
259 ..Default::default()
260 },
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000261 Domain::SELINUX => KeyDescriptor { domain, nspace: namespace, ..Default::default() },
262 _ => {
263 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!(
264 "List entries is only supported for Domain::APP and Domain::SELINUX."
265 ))
266 }
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800267 };
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.
Chris Wailes20f50df2022-04-19 17:23:52 -0700274 if let Err(e) = check_key_permission(KeyPerm::GetInfo, &k, &None) {
275 if let Some(selinux::Error::PermissionDenied) =
Rajesh Nyamagoud16198a32022-07-26 18:45:55 +0000276 e.root_cause().downcast_ref::<selinux::Error>()
277 {
Chris Wailes20f50df2022-04-19 17:23:52 -0700278 check_keystore_permission(KeystorePerm::List)
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000279 .context(ks_err!("While checking keystore permission."))?;
Chris Wailes20f50df2022-04-19 17:23:52 -0700280 if namespace != -1 {
281 k.nspace = namespace;
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800282 }
Chris Wailes20f50df2022-04-19 17:23:52 -0700283 } else {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000284 return Err(e).context(ks_err!("While checking key permission."))?;
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800285 }
Chris Wailes20f50df2022-04-19 17:23:52 -0700286 }
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800287
John Wu16db29e2022-01-13 15:21:43 -0800288 DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700289 }
290
291 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800292 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800293 let super_key =
294 SUPER_KEY.read().unwrap().get_per_boot_key_by_user_id(uid_to_android_user(caller_uid));
295
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800296 DB.with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800297 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700298 db.borrow_mut().unbind_key(key, KeyType::Client, caller_uid, |k, av| {
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000299 check_key_permission(KeyPerm::Delete, k, &av)
300 .context(ks_err!("During delete_key."))
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000301 })
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800302 })
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800303 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000304 .context(ks_err!("Trying to unbind the key."))?;
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800305 Ok(())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700306 }
307
308 fn grant(
309 &self,
310 key: &KeyDescriptor,
311 grantee_uid: i32,
312 access_vector: permission::KeyPermSet,
313 ) -> Result<KeyDescriptor> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000314 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800315 let super_key =
316 SUPER_KEY.read().unwrap().get_per_boot_key_by_user_id(uid_to_android_user(caller_uid));
317
Janis Danisevskis1af91262020-08-10 14:58:08 -0700318 DB.with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800319 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000320 db.borrow_mut().grant(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700321 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000322 caller_uid,
323 grantee_uid as u32,
324 access_vector,
325 |k, av| check_grant_permission(*av, k).context("During grant."),
326 )
327 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700328 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000329 .context(ks_err!("KeystoreService::grant."))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700330 }
331
332 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
333 DB.with(|db| {
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700334 db.borrow_mut().ungrant(key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700335 check_key_permission(KeyPerm::Grant, k, &None)
Janis Danisevskis66784c42021-01-27 08:40:25 -0800336 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700337 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000338 .context(ks_err!("KeystoreService::ungrant."))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700339 }
340}
341
342impl binder::Interface for KeystoreService {}
343
344// Implementation of IKeystoreService. See AIDL spec at
345// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
346impl IKeystoreService for KeystoreService {
347 fn getSecurityLevel(
348 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700349 security_level: SecurityLevel,
Stephen Crane23cf7242022-01-19 17:49:46 +0000350 ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000351 let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, move || {
352 format!("security_level: {}", security_level.0)
353 });
Max Bires8e93d2b2021-01-14 13:17:59 -0800354 map_or_log_err(self.get_security_level(security_level), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700355 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000356 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000357 let _wp = wd::watch_millis("IKeystoreService::get_key_entry", 500);
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700358 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700359 }
360 fn updateSubcomponent(
361 &self,
362 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700363 public_cert: Option<&[u8]>,
364 certificate_chain: Option<&[u8]>,
Stephen Crane23cf7242022-01-19 17:49:46 +0000365 ) -> binder::Result<()> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000366 let _wp = wd::watch_millis("IKeystoreService::updateSubcomponent", 500);
Janis Danisevskis1af91262020-08-10 14:58:08 -0700367 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
368 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000369 fn listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000370 let _wp = wd::watch_millis("IKeystoreService::listEntries", 500);
Janis Danisevskis1af91262020-08-10 14:58:08 -0700371 map_or_log_err(self.list_entries(domain, namespace), Ok)
372 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000373 fn deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000374 let _wp = wd::watch_millis("IKeystoreService::deleteKey", 500);
Pavel Grafov94243c22021-04-21 18:03:11 +0100375 let result = self.delete_key(key);
376 log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
377 map_or_log_err(result, Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700378 }
379 fn grant(
380 &self,
381 key: &KeyDescriptor,
382 grantee_uid: i32,
383 access_vector: i32,
Stephen Crane23cf7242022-01-19 17:49:46 +0000384 ) -> binder::Result<KeyDescriptor> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000385 let _wp = wd::watch_millis("IKeystoreService::grant", 500);
Janis Danisevskis1af91262020-08-10 14:58:08 -0700386 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
387 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000388 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000389 let _wp = wd::watch_millis("IKeystoreService::ungrant", 500);
Janis Danisevskis1af91262020-08-10 14:58:08 -0700390 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
391 }
392}