blob: 6aa7ed5ce708fcca935095d9433a6270efb7d361 [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
15// TODO remove when fully implemented.
16#![allow(unused_variables)]
17
18//! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
19//! AIDL spec.
20
Max Bires8e93d2b2021-01-14 13:17:59 -080021use std::collections::HashMap;
22
Janis Danisevskise92a5e62020-12-02 12:57:41 -080023use crate::permission::{KeyPerm, KeystorePerm};
Janis Danisevskis1af91262020-08-10 14:58:08 -070024use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070025use crate::utils::{
Janis Danisevskise92a5e62020-12-02 12:57:41 -080026 check_grant_permission, check_key_permission, check_keystore_permission,
27 key_parameters_to_authorizations, Asp,
Janis Danisevskis04b02832020-10-26 09:21:40 -070028};
Max Bires8e93d2b2021-01-14 13:17:59 -080029use crate::{database::Uuid, globals::DB};
30use crate::{database::KEYSTORE_UUID, permission};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080031use crate::{
32 database::{KeyEntryLoadBits, KeyType, SubComponentType},
33 error::ResponseCode,
34};
Janis Danisevskis4507f3b2021-01-13 16:34:39 -080035use crate::{
36 error::{self, map_or_log_err, ErrorCode},
37 gc::Gc,
38};
Shawn Willden708744a2020-12-11 13:05:27 +000039use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Janis Danisevskis1af91262020-08-10 14:58:08 -070040use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070041 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
42 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
43 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070044};
Max Bires8e93d2b2021-01-14 13:17:59 -080045use anyhow::{Context, Result};
Stephen Crane221bbb52020-12-16 15:52:10 -080046use binder::{IBinder, Strong, ThreadState};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080047use error::Error;
48use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070049
50/// Implementation of the IKeystoreService.
Max Bires8e93d2b2021-01-14 13:17:59 -080051#[derive(Default)]
Janis Danisevskis1af91262020-08-10 14:58:08 -070052pub struct KeystoreService {
Max Bires8e93d2b2021-01-14 13:17:59 -080053 i_sec_level_by_uuid: HashMap<Uuid, Asp>,
54 uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
Janis Danisevskis1af91262020-08-10 14:58:08 -070055}
56
57impl KeystoreService {
58 /// Create a new instance of the Keystore 2.0 service.
Stephen Crane221bbb52020-12-16 15:52:10 -080059 pub fn new_native_binder() -> Result<Strong<dyn IKeystoreService>> {
Max Bires8e93d2b2021-01-14 13:17:59 -080060 let mut result: Self = Default::default();
61 let (dev, uuid) =
Janis Danisevskisba998992020-12-29 16:08:40 -080062 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
Max Bires8e93d2b2021-01-14 13:17:59 -080063 .context(concat!(
64 "In KeystoreService::new_native_binder: ",
65 "Trying to construct mandatory security level TEE."
66 ))
67 .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))?;
68 result.i_sec_level_by_uuid.insert(uuid, dev);
69 result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid);
Janis Danisevskisba998992020-12-29 16:08:40 -080070
Max Bires8e93d2b2021-01-14 13:17:59 -080071 // Strongbox is optional, so we ignore errors and turn the result into an Option.
72 if let Ok((dev, uuid)) = KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX)
73 .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))
74 {
75 result.i_sec_level_by_uuid.insert(uuid, dev);
76 result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
77 }
78
79 let result = BnKeystoreService::new_binder(result);
Janis Danisevskis1af91262020-08-10 14:58:08 -070080 result.as_binder().set_requesting_sid(true);
81 Ok(result)
82 }
83
Max Bires8e93d2b2021-01-14 13:17:59 -080084 fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel {
85 self.uuid_by_sec_level
86 .iter()
87 .find(|(_, v)| **v == *uuid)
88 .map(|(s, _)| *s)
89 .unwrap_or(SecurityLevel::SOFTWARE)
90 }
91
Stephen Crane221bbb52020-12-16 15:52:10 -080092 fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -080093 if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
94 dev.get_interface().context("In get_i_sec_level_by_uuid.")
95 } else {
96 Err(error::Error::sys())
97 .context("In get_i_sec_level_by_uuid: KeyMint instance for key not found.")
98 }
Janis Danisevskisba998992020-12-29 16:08:40 -080099 }
100
Janis Danisevskis1af91262020-08-10 14:58:08 -0700101 fn get_security_level(
102 &self,
Max Bires8e93d2b2021-01-14 13:17:59 -0800103 sec_level: SecurityLevel,
Stephen Crane221bbb52020-12-16 15:52:10 -0800104 ) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800105 if let Some(dev) = self
106 .uuid_by_sec_level
107 .get(&sec_level)
108 .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid))
109 {
110 dev.get_interface().context("In get_security_level.")
111 } else {
112 Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
113 .context("In get_security_level: No such security level.")
114 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700115 }
116
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700117 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800118 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700119 .with(|db| {
120 db.borrow_mut().load_key_entry(
Janis Danisevskis66784c42021-01-27 08:40:25 -0800121 &key,
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800122 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700123 KeyEntryLoadBits::PUBLIC,
124 ThreadState::get_calling_uid(),
125 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
126 )
127 })
128 .context("In get_key_entry, while trying to load key info.")?;
129
Janis Danisevskis377d1002021-01-27 19:07:48 -0800130 let i_sec_level = if !key_entry.pure_cert() {
131 Some(
Max Bires8e93d2b2021-01-14 13:17:59 -0800132 self.get_i_sec_level_by_uuid(key_entry.km_uuid())
133 .context("In get_key_entry: Trying to get security level proxy.")?,
Janis Danisevskis377d1002021-01-27 19:07:48 -0800134 )
135 } else {
136 None
137 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700138
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700139 Ok(KeyEntryResponse {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800140 iSecurityLevel: i_sec_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700141 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700142 key: KeyDescriptor {
143 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800144 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700145 ..Default::default()
146 },
Max Bires8e93d2b2021-01-14 13:17:59 -0800147 keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700148 certificate: key_entry.take_cert(),
149 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800150 modificationTimeMs: key_entry
151 .metadata()
152 .creation_date()
153 .map(|d| d.to_millis_epoch())
154 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
155 .context("In get_key_entry: Trying to get creation date.")?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700156 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700157 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700158 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700159 }
160
161 fn update_subcomponent(
162 &self,
163 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700164 public_cert: Option<&[u8]>,
165 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700166 ) -> Result<()> {
167 DB.with::<_, Result<()>>(|db| {
168 let mut db = db.borrow_mut();
Janis Danisevskis377d1002021-01-27 19:07:48 -0800169 let entry = match db.load_key_entry(
Janis Danisevskis66784c42021-01-27 08:40:25 -0800170 &key,
Janis Danisevskis377d1002021-01-27 19:07:48 -0800171 KeyType::Client,
172 KeyEntryLoadBits::NONE,
173 ThreadState::get_calling_uid(),
174 |k, av| {
175 check_key_permission(KeyPerm::update(), k, &av)
176 .context("In update_subcomponent.")
177 },
178 ) {
179 Err(e) => match e.root_cause().downcast_ref::<Error>() {
180 Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
181 _ => Err(e),
182 },
183 Ok(v) => Ok(Some(v)),
184 }
185 .context("Failed to load key entry.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700186
Janis Danisevskis377d1002021-01-27 19:07:48 -0800187 if let Some((key_id_guard, key_entry)) = entry {
188 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700189 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800190
191 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain)
192 .context("Failed to update cert chain subcomponent.")?;
193 return Ok(());
Janis Danisevskis1af91262020-08-10 14:58:08 -0700194 }
195
Janis Danisevskis377d1002021-01-27 19:07:48 -0800196 // If we reach this point we have to check the special condition where a certificate
197 // entry may be made.
198 if !(public_cert.is_none() && certificate_chain.is_some()) {
199 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)).context("No key to update.");
Janis Danisevskis1af91262020-08-10 14:58:08 -0700200 }
Janis Danisevskis377d1002021-01-27 19:07:48 -0800201
202 // So we know that we have a certificate chain and no public cert.
203 // Now check that we have everything we need to make a new certificate entry.
204 let key = match (key.domain, &key.alias) {
205 (Domain::APP, Some(ref alias)) => KeyDescriptor {
206 domain: Domain::APP,
207 nspace: ThreadState::get_calling_uid() as i64,
208 alias: Some(alias.clone()),
209 blob: None,
210 },
211 (Domain::SELINUX, Some(_)) => key.clone(),
212 _ => {
213 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
214 .context("Domain must be APP or SELINUX to insert a certificate.")
215 }
216 };
217
218 // Security critical: This must return on failure. Do not remove the `?`;
219 check_key_permission(KeyPerm::rebind(), &key, &None)
220 .context("Caller does not have permission to insert this certificate.")?;
221
Janis Danisevskis66784c42021-01-27 08:40:25 -0800222 db.store_new_certificate(&key, certificate_chain.unwrap(), &KEYSTORE_UUID)
Janis Danisevskis377d1002021-01-27 19:07:48 -0800223 .context("Failed to insert new certificate.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700224 Ok(())
225 })
226 .context("In update_subcomponent.")
227 }
228
229 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800230 let mut k = match domain {
231 Domain::APP => KeyDescriptor {
232 domain,
233 nspace: ThreadState::get_calling_uid() as u64 as i64,
234 ..Default::default()
235 },
236 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
237 _ => return Err(Error::perm()).context(
238 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
239 ),
240 };
241
242 // First we check if the caller has the info permission for the selected domain/namespace.
243 // By default we use the calling uid as namespace if domain is Domain::APP.
244 // If the first check fails we check if the caller has the list permission allowing to list
245 // any namespace. In that case we also adjust the queried namespace if a specific uid was
246 // selected.
247 match check_key_permission(KeyPerm::get_info(), &k, &None) {
248 Err(e) => {
249 if let Some(selinux::Error::PermissionDenied) =
250 e.root_cause().downcast_ref::<selinux::Error>()
251 {
252 check_keystore_permission(KeystorePerm::list())
253 .context("In list_entries: While checking keystore permission.")?;
254 if namespace != -1 {
255 k.nspace = namespace;
256 }
257 } else {
258 return Err(e).context("In list_entries: While checking key permission.")?;
259 }
260 }
261 Ok(()) => {}
262 };
263
264 DB.with(|db| {
265 let mut db = db.borrow_mut();
266 db.list(k.domain, k.nspace)
267 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700268 }
269
270 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800271 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskis4507f3b2021-01-13 16:34:39 -0800272 let need_gc = DB
273 .with(|db| {
Janis Danisevskis66784c42021-01-27 08:40:25 -0800274 db.borrow_mut().unbind_key(&key, KeyType::Client, caller_uid, |k, av| {
Janis Danisevskis4507f3b2021-01-13 16:34:39 -0800275 check_key_permission(KeyPerm::delete(), k, &av).context("During delete_key.")
276 })
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800277 })
Janis Danisevskis4507f3b2021-01-13 16:34:39 -0800278 .context("In delete_key: Trying to unbind the key.")?;
279 if need_gc {
280 Gc::notify_gc();
281 }
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800282 Ok(())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700283 }
284
285 fn grant(
286 &self,
287 key: &KeyDescriptor,
288 grantee_uid: i32,
289 access_vector: permission::KeyPermSet,
290 ) -> Result<KeyDescriptor> {
291 DB.with(|db| {
292 db.borrow_mut().grant(
Janis Danisevskis66784c42021-01-27 08:40:25 -0800293 &key,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700294 ThreadState::get_calling_uid(),
295 grantee_uid as u32,
296 access_vector,
297 |k, av| check_grant_permission(*av, k).context("During grant."),
298 )
299 })
300 .context("In KeystoreService::grant.")
301 }
302
303 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
304 DB.with(|db| {
Janis Danisevskis66784c42021-01-27 08:40:25 -0800305 db.borrow_mut().ungrant(&key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
306 check_key_permission(KeyPerm::grant(), k, &None)
307 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700308 })
309 .context("In KeystoreService::ungrant.")
310 }
311}
312
313impl binder::Interface for KeystoreService {}
314
315// Implementation of IKeystoreService. See AIDL spec at
316// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
317impl IKeystoreService for KeystoreService {
318 fn getSecurityLevel(
319 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700320 security_level: SecurityLevel,
Stephen Crane221bbb52020-12-16 15:52:10 -0800321 ) -> binder::public_api::Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800322 map_or_log_err(self.get_security_level(security_level), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700323 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700324 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
325 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700326 }
327 fn updateSubcomponent(
328 &self,
329 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700330 public_cert: Option<&[u8]>,
331 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700332 ) -> binder::public_api::Result<()> {
333 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
334 }
335 fn listEntries(
336 &self,
337 domain: Domain,
338 namespace: i64,
339 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
340 map_or_log_err(self.list_entries(domain, namespace), Ok)
341 }
342 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
343 map_or_log_err(self.delete_key(key), Ok)
344 }
345 fn grant(
346 &self,
347 key: &KeyDescriptor,
348 grantee_uid: i32,
349 access_vector: i32,
350 ) -> binder::public_api::Result<KeyDescriptor> {
351 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
352 }
353 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
354 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
355 }
356}