blob: e57a9b7b2caa081cc8e9dae2fa35c0a9db5d3aa5 [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
Janis Danisevskis1af91262020-08-10 14:58:08 -070021use crate::globals::DB;
22use crate::permission;
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};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080029use crate::{
30 database::{KeyEntryLoadBits, KeyType, SubComponentType},
31 error::ResponseCode,
32};
Janis Danisevskis4507f3b2021-01-13 16:34:39 -080033use crate::{
34 error::{self, map_or_log_err, ErrorCode},
35 gc::Gc,
36};
Shawn Willden708744a2020-12-11 13:05:27 +000037use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Janis Danisevskis1af91262020-08-10 14:58:08 -070038use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070039 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
40 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
41 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070042};
43use anyhow::{anyhow, Context, Result};
44use binder::{IBinder, Interface, ThreadState};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080045use error::Error;
46use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070047
48/// Implementation of the IKeystoreService.
49pub struct KeystoreService {
Janis Danisevskisba998992020-12-29 16:08:40 -080050 sec_level_tee: Asp,
51 sec_level_strongbox: Option<Asp>,
Janis Danisevskis1af91262020-08-10 14:58:08 -070052}
53
54impl KeystoreService {
55 /// Create a new instance of the Keystore 2.0 service.
56 pub fn new_native_binder() -> Result<impl IKeystoreService> {
Janis Danisevskisba998992020-12-29 16:08:40 -080057 let tee = KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
58 .map(|tee| Asp::new(tee.as_binder()))
59 .context(concat!(
60 "In KeystoreService::new_native_binder: ",
61 "Trying to construct mendatory security level TEE."
62 ))?;
63 // Strongbox is optional, so we ignore errors and turn the result into an Option.
64 let strongbox =
65 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
66 .map(|tee| Asp::new(tee.as_binder()))
67 .ok();
68
Janis Danisevskis1af91262020-08-10 14:58:08 -070069 let result = BnKeystoreService::new_binder(Self {
Janis Danisevskisba998992020-12-29 16:08:40 -080070 sec_level_tee: tee,
71 sec_level_strongbox: strongbox,
Janis Danisevskis1af91262020-08-10 14:58:08 -070072 });
73 result.as_binder().set_requesting_sid(true);
74 Ok(result)
75 }
76
Janis Danisevskisba998992020-12-29 16:08:40 -080077 fn get_security_level_internal(
78 &self,
79 security_level: SecurityLevel,
80 ) -> Result<Option<Box<dyn IKeystoreSecurityLevel>>> {
81 Ok(match (security_level, &self.sec_level_strongbox) {
82 (SecurityLevel::TRUSTED_ENVIRONMENT, _) => Some(self.sec_level_tee.get_interface().context(
83 "In get_security_level_internal: Failed to get IKeystoreSecurityLevel (TEE).",
84 )?),
85 (SecurityLevel::STRONGBOX, Some(strongbox)) => Some(strongbox.get_interface().context(
86 "In get_security_level_internal: Failed to get IKeystoreSecurityLevel (Strongbox).",
87 )?),
88 _ => None,
89 })
90 }
91
Janis Danisevskis1af91262020-08-10 14:58:08 -070092 fn get_security_level(
93 &self,
94 security_level: SecurityLevel,
95 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskisba998992020-12-29 16:08:40 -080096 self.get_security_level_internal(security_level)
97 .context("In get_security_level.")?
98 .ok_or_else(|| anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)))
Janis Danisevskis1af91262020-08-10 14:58:08 -070099 }
100
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700101 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800102 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700103 .with(|db| {
104 db.borrow_mut().load_key_entry(
105 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800106 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700107 KeyEntryLoadBits::PUBLIC,
108 ThreadState::get_calling_uid(),
109 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
110 )
111 })
112 .context("In get_key_entry, while trying to load key info.")?;
113
Janis Danisevskis377d1002021-01-27 19:07:48 -0800114 let i_sec_level = if !key_entry.pure_cert() {
115 Some(
116 self.get_security_level_internal(key_entry.sec_level())
117 .context("In get_key_entry.")?
118 .ok_or_else(|| {
119 anyhow!(error::Error::sys()).context(format!(
120 concat!(
121 "Found key with security level {:?} ",
122 "but no KeyMint instance of that security level."
123 ),
124 key_entry.sec_level()
125 ))
126 })?,
127 )
128 } else {
129 None
130 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700131
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700132 Ok(KeyEntryResponse {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800133 iSecurityLevel: i_sec_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700134 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700135 key: KeyDescriptor {
136 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800137 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700138 ..Default::default()
139 },
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700140 keySecurityLevel: key_entry.sec_level(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700141 certificate: key_entry.take_cert(),
142 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800143 modificationTimeMs: key_entry
144 .metadata()
145 .creation_date()
146 .map(|d| d.to_millis_epoch())
147 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
148 .context("In get_key_entry: Trying to get creation date.")?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700149 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700150 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700151 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700152 }
153
154 fn update_subcomponent(
155 &self,
156 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700157 public_cert: Option<&[u8]>,
158 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700159 ) -> Result<()> {
160 DB.with::<_, Result<()>>(|db| {
161 let mut db = db.borrow_mut();
Janis Danisevskis377d1002021-01-27 19:07:48 -0800162 let entry = match db.load_key_entry(
163 key.clone(),
164 KeyType::Client,
165 KeyEntryLoadBits::NONE,
166 ThreadState::get_calling_uid(),
167 |k, av| {
168 check_key_permission(KeyPerm::update(), k, &av)
169 .context("In update_subcomponent.")
170 },
171 ) {
172 Err(e) => match e.root_cause().downcast_ref::<Error>() {
173 Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
174 _ => Err(e),
175 },
176 Ok(v) => Ok(Some(v)),
177 }
178 .context("Failed to load key entry.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700179
Janis Danisevskis377d1002021-01-27 19:07:48 -0800180 if let Some((key_id_guard, key_entry)) = entry {
181 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700182 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800183
184 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain)
185 .context("Failed to update cert chain subcomponent.")?;
186 return Ok(());
Janis Danisevskis1af91262020-08-10 14:58:08 -0700187 }
188
Janis Danisevskis377d1002021-01-27 19:07:48 -0800189 // If we reach this point we have to check the special condition where a certificate
190 // entry may be made.
191 if !(public_cert.is_none() && certificate_chain.is_some()) {
192 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)).context("No key to update.");
Janis Danisevskis1af91262020-08-10 14:58:08 -0700193 }
Janis Danisevskis377d1002021-01-27 19:07:48 -0800194
195 // So we know that we have a certificate chain and no public cert.
196 // Now check that we have everything we need to make a new certificate entry.
197 let key = match (key.domain, &key.alias) {
198 (Domain::APP, Some(ref alias)) => KeyDescriptor {
199 domain: Domain::APP,
200 nspace: ThreadState::get_calling_uid() as i64,
201 alias: Some(alias.clone()),
202 blob: None,
203 },
204 (Domain::SELINUX, Some(_)) => key.clone(),
205 _ => {
206 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
207 .context("Domain must be APP or SELINUX to insert a certificate.")
208 }
209 };
210
211 // Security critical: This must return on failure. Do not remove the `?`;
212 check_key_permission(KeyPerm::rebind(), &key, &None)
213 .context("Caller does not have permission to insert this certificate.")?;
214
215 db.store_new_certificate(key, certificate_chain.unwrap())
216 .context("Failed to insert new certificate.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700217 Ok(())
218 })
219 .context("In update_subcomponent.")
220 }
221
222 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800223 let mut k = match domain {
224 Domain::APP => KeyDescriptor {
225 domain,
226 nspace: ThreadState::get_calling_uid() as u64 as i64,
227 ..Default::default()
228 },
229 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
230 _ => return Err(Error::perm()).context(
231 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
232 ),
233 };
234
235 // First we check if the caller has the info permission for the selected domain/namespace.
236 // By default we use the calling uid as namespace if domain is Domain::APP.
237 // If the first check fails we check if the caller has the list permission allowing to list
238 // any namespace. In that case we also adjust the queried namespace if a specific uid was
239 // selected.
240 match check_key_permission(KeyPerm::get_info(), &k, &None) {
241 Err(e) => {
242 if let Some(selinux::Error::PermissionDenied) =
243 e.root_cause().downcast_ref::<selinux::Error>()
244 {
245 check_keystore_permission(KeystorePerm::list())
246 .context("In list_entries: While checking keystore permission.")?;
247 if namespace != -1 {
248 k.nspace = namespace;
249 }
250 } else {
251 return Err(e).context("In list_entries: While checking key permission.")?;
252 }
253 }
254 Ok(()) => {}
255 };
256
257 DB.with(|db| {
258 let mut db = db.borrow_mut();
259 db.list(k.domain, k.nspace)
260 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700261 }
262
263 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800264 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskis4507f3b2021-01-13 16:34:39 -0800265 let need_gc = DB
266 .with(|db| {
267 db.borrow_mut().unbind_key(key.clone(), KeyType::Client, caller_uid, |k, av| {
268 check_key_permission(KeyPerm::delete(), k, &av).context("During delete_key.")
269 })
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800270 })
Janis Danisevskis4507f3b2021-01-13 16:34:39 -0800271 .context("In delete_key: Trying to unbind the key.")?;
272 if need_gc {
273 Gc::notify_gc();
274 }
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800275 Ok(())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700276 }
277
278 fn grant(
279 &self,
280 key: &KeyDescriptor,
281 grantee_uid: i32,
282 access_vector: permission::KeyPermSet,
283 ) -> Result<KeyDescriptor> {
284 DB.with(|db| {
285 db.borrow_mut().grant(
286 key.clone(),
287 ThreadState::get_calling_uid(),
288 grantee_uid as u32,
289 access_vector,
290 |k, av| check_grant_permission(*av, k).context("During grant."),
291 )
292 })
293 .context("In KeystoreService::grant.")
294 }
295
296 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
297 DB.with(|db| {
298 db.borrow_mut().ungrant(
299 key.clone(),
300 ThreadState::get_calling_uid(),
301 grantee_uid as u32,
302 |k| check_key_permission(KeyPerm::grant(), k, &None),
303 )
304 })
305 .context("In KeystoreService::ungrant.")
306 }
307}
308
309impl binder::Interface for KeystoreService {}
310
311// Implementation of IKeystoreService. See AIDL spec at
312// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
313impl IKeystoreService for KeystoreService {
314 fn getSecurityLevel(
315 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700316 security_level: SecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700317 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskis04b02832020-10-26 09:21:40 -0700318 map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700319 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700320 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
321 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700322 }
323 fn updateSubcomponent(
324 &self,
325 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700326 public_cert: Option<&[u8]>,
327 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700328 ) -> binder::public_api::Result<()> {
329 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
330 }
331 fn listEntries(
332 &self,
333 domain: Domain,
334 namespace: i64,
335 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
336 map_or_log_err(self.list_entries(domain, namespace), Ok)
337 }
338 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
339 map_or_log_err(self.delete_key(key), Ok)
340 }
341 fn grant(
342 &self,
343 key: &KeyDescriptor,
344 grantee_uid: i32,
345 access_vector: i32,
346 ) -> binder::public_api::Result<KeyDescriptor> {
347 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
348 }
349 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
350 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
351 }
352}