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