blob: 2abf9be69d4c81c5756bbd9c2bab9dd8702105d5 [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 {
47 sec_level: Asp,
48}
49
50impl KeystoreService {
51 /// Create a new instance of the Keystore 2.0 service.
52 pub fn new_native_binder() -> Result<impl IKeystoreService> {
53 let result = BnKeystoreService::new_binder(Self {
54 sec_level: Asp::new({
55 let sec_level =
56 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
57 .context("While trying to create IKeystoreSecurityLevel")?;
58 sec_level.as_binder()
59 }),
60 });
61 result.as_binder().set_requesting_sid(true);
62 Ok(result)
63 }
64
65 fn get_security_level(
66 &self,
67 security_level: SecurityLevel,
68 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
69 match security_level {
70 SecurityLevel::TRUSTED_ENVIRONMENT => self
71 .sec_level
72 .get_interface()
73 .context("In get_security_level: Failed to get IKeystoreSecurityLevel."),
74 _ => Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
75 }
76 }
77
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070078 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskisaec14592020-11-12 09:41:49 -080079 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -070080 .with(|db| {
81 db.borrow_mut().load_key_entry(
82 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -080083 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -070084 KeyEntryLoadBits::PUBLIC,
85 ThreadState::get_calling_uid(),
86 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
87 )
88 })
89 .context("In get_key_entry, while trying to load key info.")?;
90
91 let i_sec_level = match key_entry.sec_level() {
92 SecurityLevel::TRUSTED_ENVIRONMENT => self
93 .sec_level
94 .get_interface()
95 .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
96 _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
97 };
98
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070099 Ok(KeyEntryResponse {
100 iSecurityLevel: Some(i_sec_level),
101 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700102 key: KeyDescriptor {
103 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800104 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700105 ..Default::default()
106 },
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700107 keySecurityLevel: key_entry.sec_level(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700108 certificate: key_entry.take_cert(),
109 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800110 modificationTimeMs: key_entry
111 .metadata()
112 .creation_date()
113 .map(|d| d.to_millis_epoch())
114 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
115 .context("In get_key_entry: Trying to get creation date.")?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700116 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700117 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700118 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700119 }
120
121 fn update_subcomponent(
122 &self,
123 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700124 public_cert: Option<&[u8]>,
125 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700126 ) -> Result<()> {
127 DB.with::<_, Result<()>>(|db| {
128 let mut db = db.borrow_mut();
Janis Danisevskisaec14592020-11-12 09:41:49 -0800129 let (key_id_guard, key_entry) = db
Janis Danisevskis1af91262020-08-10 14:58:08 -0700130 .load_key_entry(
131 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800132 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700133 KeyEntryLoadBits::NONE,
134 ThreadState::get_calling_uid(),
135 |k, av| {
136 check_key_permission(KeyPerm::update(), k, &av)
137 .context("In update_subcomponent.")
138 },
139 )
140 .context("Failed to load key_entry.")?;
141
142 if let Some(cert) = public_cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800143 db.insert_blob(&key_id_guard, SubComponentType::CERT, cert, key_entry.sec_level())
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700144 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700145 }
146
147 if let Some(cert_chain) = certificate_chain {
148 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800149 &key_id_guard,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700150 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700151 cert_chain,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700152 key_entry.sec_level(),
153 )
154 .context("Failed to update cert chain subcomponent.")?;
155 }
156 Ok(())
157 })
158 .context("In update_subcomponent.")
159 }
160
161 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800162 let mut k = match domain {
163 Domain::APP => KeyDescriptor {
164 domain,
165 nspace: ThreadState::get_calling_uid() as u64 as i64,
166 ..Default::default()
167 },
168 Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
169 _ => return Err(Error::perm()).context(
170 "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
171 ),
172 };
173
174 // First we check if the caller has the info permission for the selected domain/namespace.
175 // By default we use the calling uid as namespace if domain is Domain::APP.
176 // If the first check fails we check if the caller has the list permission allowing to list
177 // any namespace. In that case we also adjust the queried namespace if a specific uid was
178 // selected.
179 match check_key_permission(KeyPerm::get_info(), &k, &None) {
180 Err(e) => {
181 if let Some(selinux::Error::PermissionDenied) =
182 e.root_cause().downcast_ref::<selinux::Error>()
183 {
184 check_keystore_permission(KeystorePerm::list())
185 .context("In list_entries: While checking keystore permission.")?;
186 if namespace != -1 {
187 k.nspace = namespace;
188 }
189 } else {
190 return Err(e).context("In list_entries: While checking key permission.")?;
191 }
192 }
193 Ok(()) => {}
194 };
195
196 DB.with(|db| {
197 let mut db = db.borrow_mut();
198 db.list(k.domain, k.nspace)
199 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700200 }
201
202 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
203 // TODO implement.
204 Err(anyhow!(error::Error::sys()))
205 }
206
207 fn grant(
208 &self,
209 key: &KeyDescriptor,
210 grantee_uid: i32,
211 access_vector: permission::KeyPermSet,
212 ) -> Result<KeyDescriptor> {
213 DB.with(|db| {
214 db.borrow_mut().grant(
215 key.clone(),
216 ThreadState::get_calling_uid(),
217 grantee_uid as u32,
218 access_vector,
219 |k, av| check_grant_permission(*av, k).context("During grant."),
220 )
221 })
222 .context("In KeystoreService::grant.")
223 }
224
225 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
226 DB.with(|db| {
227 db.borrow_mut().ungrant(
228 key.clone(),
229 ThreadState::get_calling_uid(),
230 grantee_uid as u32,
231 |k| check_key_permission(KeyPerm::grant(), k, &None),
232 )
233 })
234 .context("In KeystoreService::ungrant.")
235 }
236}
237
238impl binder::Interface for KeystoreService {}
239
240// Implementation of IKeystoreService. See AIDL spec at
241// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
242impl IKeystoreService for KeystoreService {
243 fn getSecurityLevel(
244 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700245 security_level: SecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700246 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskis04b02832020-10-26 09:21:40 -0700247 map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700248 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700249 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
250 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700251 }
252 fn updateSubcomponent(
253 &self,
254 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700255 public_cert: Option<&[u8]>,
256 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700257 ) -> binder::public_api::Result<()> {
258 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
259 }
260 fn listEntries(
261 &self,
262 domain: Domain,
263 namespace: i64,
264 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
265 map_or_log_err(self.list_entries(domain, namespace), Ok)
266 }
267 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
268 map_or_log_err(self.delete_key(key), Ok)
269 }
270 fn grant(
271 &self,
272 key: &KeyDescriptor,
273 grantee_uid: i32,
274 access_vector: i32,
275 ) -> binder::public_api::Result<KeyDescriptor> {
276 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
277 }
278 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
279 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
280 }
281}