xref: /aosp_15_r20/system/security/keystore2/src/service.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
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