blob: d185025441945de939923a5e41a44c5c509b8c02 [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::error::{self, map_or_log_err, ErrorCode};
22use crate::globals::DB;
23use crate::permission;
Janis Danisevskise92a5e62020-12-02 12:57:41 -080024use crate::permission::{KeyPerm, KeystorePerm};
Janis Danisevskis1af91262020-08-10 14:58:08 -070025use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070026use crate::utils::{
Janis Danisevskise92a5e62020-12-02 12:57:41 -080027 check_grant_permission, check_key_permission, check_keystore_permission,
28 key_parameters_to_authorizations, Asp,
Janis Danisevskis04b02832020-10-26 09:21:40 -070029};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080030use crate::{
31 database::{KeyEntryLoadBits, KeyType, SubComponentType},
32 error::ResponseCode,
33};
Shawn Willden708744a2020-12-11 13:05:27 +000034use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Janis Danisevskis1af91262020-08-10 14:58:08 -070035use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070036 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
37 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
38 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070039};
40use anyhow::{anyhow, Context, Result};
41use binder::{IBinder, Interface, ThreadState};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080042use error::Error;
43use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070044
45/// Implementation of the IKeystoreService.
46pub struct KeystoreService {
Janis Danisevskisba998992020-12-29 16:08:40 -080047 sec_level_tee: Asp,
48 sec_level_strongbox: Option<Asp>,
Janis Danisevskis1af91262020-08-10 14:58:08 -070049}
50
51impl KeystoreService {
52 /// Create a new instance of the Keystore 2.0 service.
53 pub fn new_native_binder() -> Result<impl IKeystoreService> {
Janis Danisevskisba998992020-12-29 16:08:40 -080054 let tee = KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
55 .map(|tee| Asp::new(tee.as_binder()))
56 .context(concat!(
57 "In KeystoreService::new_native_binder: ",
58 "Trying to construct mendatory security level TEE."
59 ))?;
60 // Strongbox is optional, so we ignore errors and turn the result into an Option.
61 let strongbox =
62 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
63 .map(|tee| Asp::new(tee.as_binder()))
64 .ok();
65
Janis Danisevskis1af91262020-08-10 14:58:08 -070066 let result = BnKeystoreService::new_binder(Self {
Janis Danisevskisba998992020-12-29 16:08:40 -080067 sec_level_tee: tee,
68 sec_level_strongbox: strongbox,
Janis Danisevskis1af91262020-08-10 14:58:08 -070069 });
70 result.as_binder().set_requesting_sid(true);
71 Ok(result)
72 }
73
Janis Danisevskisba998992020-12-29 16:08:40 -080074 fn get_security_level_internal(
75 &self,
76 security_level: SecurityLevel,
77 ) -> Result<Option<Box<dyn IKeystoreSecurityLevel>>> {
78 Ok(match (security_level, &self.sec_level_strongbox) {
79 (SecurityLevel::TRUSTED_ENVIRONMENT, _) => Some(self.sec_level_tee.get_interface().context(
80 "In get_security_level_internal: Failed to get IKeystoreSecurityLevel (TEE).",
81 )?),
82 (SecurityLevel::STRONGBOX, Some(strongbox)) => Some(strongbox.get_interface().context(
83 "In get_security_level_internal: Failed to get IKeystoreSecurityLevel (Strongbox).",
84 )?),
85 _ => None,
86 })
87 }
88
Janis Danisevskis1af91262020-08-10 14:58:08 -070089 fn get_security_level(
90 &self,
91 security_level: SecurityLevel,
92 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskisba998992020-12-29 16:08:40 -080093 self.get_security_level_internal(security_level)
94 .context("In get_security_level.")?
95 .ok_or_else(|| anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)))
Janis Danisevskis1af91262020-08-10 14:58:08 -070096 }
97
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070098 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskisaec14592020-11-12 09:41:49 -080099 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700100 .with(|db| {
101 db.borrow_mut().load_key_entry(
102 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800103 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700104 KeyEntryLoadBits::PUBLIC,
105 ThreadState::get_calling_uid(),
106 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
107 )
108 })
109 .context("In get_key_entry, while trying to load key info.")?;
110
Janis Danisevskisba998992020-12-29 16:08:40 -0800111 let i_sec_level = self
112 .get_security_level_internal(key_entry.sec_level())
113 .context("In get_key_entry.")?
114 .ok_or_else(|| {
115 anyhow!(error::Error::sys()).context(format!(
116 concat!(
117 "Found key with security level {:?} ",
118 "but no KeyMint instance of that security level."
119 ),
120 key_entry.sec_level()
121 ))
122 })?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700123
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700124 Ok(KeyEntryResponse {
125 iSecurityLevel: Some(i_sec_level),
126 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700127 key: KeyDescriptor {
128 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800129 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700130 ..Default::default()
131 },
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700132 keySecurityLevel: key_entry.sec_level(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700133 certificate: key_entry.take_cert(),
134 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800135 modificationTimeMs: key_entry
136 .metadata()
137 .creation_date()
138 .map(|d| d.to_millis_epoch())
139 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
140 .context("In get_key_entry: Trying to get creation date.")?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700141 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700142 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700143 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700144 }
145
146 fn update_subcomponent(
147 &self,
148 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700149 public_cert: Option<&[u8]>,
150 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700151 ) -> Result<()> {
152 DB.with::<_, Result<()>>(|db| {
153 let mut db = db.borrow_mut();
Janis Danisevskisaec14592020-11-12 09:41:49 -0800154 let (key_id_guard, key_entry) = db
Janis Danisevskis1af91262020-08-10 14:58:08 -0700155 .load_key_entry(
156 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800157 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700158 KeyEntryLoadBits::NONE,
159 ThreadState::get_calling_uid(),
160 |k, av| {
161 check_key_permission(KeyPerm::update(), k, &av)
162 .context("In update_subcomponent.")
163 },
164 )
165 .context("Failed to load key_entry.")?;
166
167 if let Some(cert) = public_cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800168 db.insert_blob(&key_id_guard, SubComponentType::CERT, cert, key_entry.sec_level())
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700169 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700170 }
171
172 if let Some(cert_chain) = certificate_chain {
173 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800174 &key_id_guard,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700175 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700176 cert_chain,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700177 key_entry.sec_level(),
178 )
179 .context("Failed to update cert chain subcomponent.")?;
180 }
181 Ok(())
182 })
183 .context("In update_subcomponent.")
184 }
185
186 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800187 let mut k = match domain {
188 Domain::APP => KeyDescriptor {
189 domain,
190 nspace: ThreadState::get_calling_uid() as u64 as i64,
191 ..Default::default()
192 },
193 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
194 _ => return Err(Error::perm()).context(
195 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
196 ),
197 };
198
199 // First we check if the caller has the info permission for the selected domain/namespace.
200 // By default we use the calling uid as namespace if domain is Domain::APP.
201 // If the first check fails we check if the caller has the list permission allowing to list
202 // any namespace. In that case we also adjust the queried namespace if a specific uid was
203 // selected.
204 match check_key_permission(KeyPerm::get_info(), &k, &None) {
205 Err(e) => {
206 if let Some(selinux::Error::PermissionDenied) =
207 e.root_cause().downcast_ref::<selinux::Error>()
208 {
209 check_keystore_permission(KeystorePerm::list())
210 .context("In list_entries: While checking keystore permission.")?;
211 if namespace != -1 {
212 k.nspace = namespace;
213 }
214 } else {
215 return Err(e).context("In list_entries: While checking key permission.")?;
216 }
217 }
218 Ok(()) => {}
219 };
220
221 DB.with(|db| {
222 let mut db = db.borrow_mut();
223 db.list(k.domain, k.nspace)
224 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700225 }
226
227 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
228 // TODO implement.
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800229 Ok(())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700230 }
231
232 fn grant(
233 &self,
234 key: &KeyDescriptor,
235 grantee_uid: i32,
236 access_vector: permission::KeyPermSet,
237 ) -> Result<KeyDescriptor> {
238 DB.with(|db| {
239 db.borrow_mut().grant(
240 key.clone(),
241 ThreadState::get_calling_uid(),
242 grantee_uid as u32,
243 access_vector,
244 |k, av| check_grant_permission(*av, k).context("During grant."),
245 )
246 })
247 .context("In KeystoreService::grant.")
248 }
249
250 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
251 DB.with(|db| {
252 db.borrow_mut().ungrant(
253 key.clone(),
254 ThreadState::get_calling_uid(),
255 grantee_uid as u32,
256 |k| check_key_permission(KeyPerm::grant(), k, &None),
257 )
258 })
259 .context("In KeystoreService::ungrant.")
260 }
261}
262
263impl binder::Interface for KeystoreService {}
264
265// Implementation of IKeystoreService. See AIDL spec at
266// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
267impl IKeystoreService for KeystoreService {
268 fn getSecurityLevel(
269 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700270 security_level: SecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700271 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskis04b02832020-10-26 09:21:40 -0700272 map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700273 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700274 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
275 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700276 }
277 fn updateSubcomponent(
278 &self,
279 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700280 public_cert: Option<&[u8]>,
281 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700282 ) -> binder::public_api::Result<()> {
283 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
284 }
285 fn listEntries(
286 &self,
287 domain: Domain,
288 namespace: i64,
289 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
290 map_or_log_err(self.list_entries(domain, namespace), Ok)
291 }
292 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
293 map_or_log_err(self.delete_key(key), Ok)
294 }
295 fn grant(
296 &self,
297 key: &KeyDescriptor,
298 grantee_uid: i32,
299 access_vector: i32,
300 ) -> binder::public_api::Result<KeyDescriptor> {
301 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
302 }
303 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
304 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
305 }
306}