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