blob: cb040319579e40531376c414d0e21e911ba11bfe [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 Danisevskisaec14592020-11-12 09:41:49 -080021use crate::database::{KeyEntryLoadBits, SubComponentType};
Janis Danisevskis1af91262020-08-10 14:58:08 -070022use crate::error::{self, map_or_log_err, ErrorCode};
23use crate::globals::DB;
24use crate::permission;
Janis Danisevskise92a5e62020-12-02 12:57:41 -080025use crate::permission::{KeyPerm, KeystorePerm};
Janis Danisevskis1af91262020-08-10 14:58:08 -070026use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070027use crate::utils::{
Janis Danisevskise92a5e62020-12-02 12:57:41 -080028 check_grant_permission, check_key_permission, check_keystore_permission,
29 key_parameters_to_authorizations, Asp,
Janis Danisevskis04b02832020-10-26 09:21:40 -070030};
Shawn Willden708744a2020-12-11 13:05:27 +000031use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Janis Danisevskis1af91262020-08-10 14:58:08 -070032use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070033 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
34 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
35 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070036};
37use anyhow::{anyhow, Context, Result};
38use binder::{IBinder, Interface, ThreadState};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080039use error::Error;
40use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070041
42/// Implementation of the IKeystoreService.
43pub struct KeystoreService {
44 sec_level: Asp,
45}
46
47impl KeystoreService {
48 /// Create a new instance of the Keystore 2.0 service.
49 pub fn new_native_binder() -> Result<impl IKeystoreService> {
50 let result = BnKeystoreService::new_binder(Self {
51 sec_level: Asp::new({
52 let sec_level =
53 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
54 .context("While trying to create IKeystoreSecurityLevel")?;
55 sec_level.as_binder()
56 }),
57 });
58 result.as_binder().set_requesting_sid(true);
59 Ok(result)
60 }
61
62 fn get_security_level(
63 &self,
64 security_level: SecurityLevel,
65 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
66 match security_level {
67 SecurityLevel::TRUSTED_ENVIRONMENT => self
68 .sec_level
69 .get_interface()
70 .context("In get_security_level: Failed to get IKeystoreSecurityLevel."),
71 _ => Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
72 }
73 }
74
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070075 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskisaec14592020-11-12 09:41:49 -080076 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -070077 .with(|db| {
78 db.borrow_mut().load_key_entry(
79 key.clone(),
80 KeyEntryLoadBits::PUBLIC,
81 ThreadState::get_calling_uid(),
82 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
83 )
84 })
85 .context("In get_key_entry, while trying to load key info.")?;
86
87 let i_sec_level = match key_entry.sec_level() {
88 SecurityLevel::TRUSTED_ENVIRONMENT => self
89 .sec_level
90 .get_interface()
91 .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
92 _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
93 };
94
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070095 Ok(KeyEntryResponse {
96 iSecurityLevel: Some(i_sec_level),
97 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -070098 key: KeyDescriptor {
99 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800100 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700101 ..Default::default()
102 },
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700103 keySecurityLevel: key_entry.sec_level(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700104 certificate: key_entry.take_cert(),
105 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskis04b02832020-10-26 09:21:40 -0700106 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700107 ..Default::default()
108 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700109 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700110 }
111
112 fn update_subcomponent(
113 &self,
114 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700115 public_cert: Option<&[u8]>,
116 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700117 ) -> Result<()> {
118 DB.with::<_, Result<()>>(|db| {
119 let mut db = db.borrow_mut();
Janis Danisevskisaec14592020-11-12 09:41:49 -0800120 let (key_id_guard, key_entry) = db
Janis Danisevskis1af91262020-08-10 14:58:08 -0700121 .load_key_entry(
122 key.clone(),
123 KeyEntryLoadBits::NONE,
124 ThreadState::get_calling_uid(),
125 |k, av| {
126 check_key_permission(KeyPerm::update(), k, &av)
127 .context("In update_subcomponent.")
128 },
129 )
130 .context("Failed to load key_entry.")?;
131
132 if let Some(cert) = public_cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800133 db.insert_blob(&key_id_guard, SubComponentType::CERT, cert, key_entry.sec_level())
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700134 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700135 }
136
137 if let Some(cert_chain) = certificate_chain {
138 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800139 &key_id_guard,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700140 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700141 cert_chain,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700142 key_entry.sec_level(),
143 )
144 .context("Failed to update cert chain subcomponent.")?;
145 }
146 Ok(())
147 })
148 .context("In update_subcomponent.")
149 }
150
151 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800152 let mut k = match domain {
153 Domain::APP => KeyDescriptor {
154 domain,
155 nspace: ThreadState::get_calling_uid() as u64 as i64,
156 ..Default::default()
157 },
158 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
159 _ => return Err(Error::perm()).context(
160 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
161 ),
162 };
163
164 // First we check if the caller has the info permission for the selected domain/namespace.
165 // By default we use the calling uid as namespace if domain is Domain::APP.
166 // If the first check fails we check if the caller has the list permission allowing to list
167 // any namespace. In that case we also adjust the queried namespace if a specific uid was
168 // selected.
169 match check_key_permission(KeyPerm::get_info(), &k, &None) {
170 Err(e) => {
171 if let Some(selinux::Error::PermissionDenied) =
172 e.root_cause().downcast_ref::<selinux::Error>()
173 {
174 check_keystore_permission(KeystorePerm::list())
175 .context("In list_entries: While checking keystore permission.")?;
176 if namespace != -1 {
177 k.nspace = namespace;
178 }
179 } else {
180 return Err(e).context("In list_entries: While checking key permission.")?;
181 }
182 }
183 Ok(()) => {}
184 };
185
186 DB.with(|db| {
187 let mut db = db.borrow_mut();
188 db.list(k.domain, k.nspace)
189 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700190 }
191
192 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
193 // TODO implement.
194 Err(anyhow!(error::Error::sys()))
195 }
196
197 fn grant(
198 &self,
199 key: &KeyDescriptor,
200 grantee_uid: i32,
201 access_vector: permission::KeyPermSet,
202 ) -> Result<KeyDescriptor> {
203 DB.with(|db| {
204 db.borrow_mut().grant(
205 key.clone(),
206 ThreadState::get_calling_uid(),
207 grantee_uid as u32,
208 access_vector,
209 |k, av| check_grant_permission(*av, k).context("During grant."),
210 )
211 })
212 .context("In KeystoreService::grant.")
213 }
214
215 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
216 DB.with(|db| {
217 db.borrow_mut().ungrant(
218 key.clone(),
219 ThreadState::get_calling_uid(),
220 grantee_uid as u32,
221 |k| check_key_permission(KeyPerm::grant(), k, &None),
222 )
223 })
224 .context("In KeystoreService::ungrant.")
225 }
226}
227
228impl binder::Interface for KeystoreService {}
229
230// Implementation of IKeystoreService. See AIDL spec at
231// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
232impl IKeystoreService for KeystoreService {
233 fn getSecurityLevel(
234 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700235 security_level: SecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700236 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskis04b02832020-10-26 09:21:40 -0700237 map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700238 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700239 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
240 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700241 }
242 fn updateSubcomponent(
243 &self,
244 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700245 public_cert: Option<&[u8]>,
246 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700247 ) -> binder::public_api::Result<()> {
248 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
249 }
250 fn listEntries(
251 &self,
252 domain: Domain,
253 namespace: i64,
254 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
255 map_or_log_err(self.list_entries(domain, namespace), Ok)
256 }
257 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
258 map_or_log_err(self.delete_key(key), Ok)
259 }
260 fn grant(
261 &self,
262 key: &KeyDescriptor,
263 grantee_uid: i32,
264 access_vector: i32,
265 ) -> binder::public_api::Result<KeyDescriptor> {
266 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
267 }
268 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
269 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
270 }
271}