blob: d0c44e0c29aa3ef35b7ff9c450a9498d2916d2d1 [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
21use crate::database::{KeyEntry, KeyEntryLoadBits, SubComponentType};
22use crate::error::{self, map_or_log_err, ErrorCode};
23use crate::globals::DB;
24use crate::permission;
25use crate::permission::KeyPerm;
26use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070027use crate::utils::{
28 check_grant_permission, check_key_permission, key_parameters_to_authorizations, Asp,
29};
30use android_hardware_keymint::aidl::android::hardware::keymint::SecurityLevel::SecurityLevel;
Janis Danisevskis1af91262020-08-10 14:58:08 -070031use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070032 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
33 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
34 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis04b02832020-10-26 09:21:40 -070035 SecurityLevel::SecurityLevel as KsSecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -070036};
37use anyhow::{anyhow, Context, Result};
38use binder::{IBinder, Interface, ThreadState};
39
40/// Implementation of the IKeystoreService.
41pub struct KeystoreService {
42 sec_level: Asp,
43}
44
45impl KeystoreService {
46 /// Create a new instance of the Keystore 2.0 service.
47 pub fn new_native_binder() -> Result<impl IKeystoreService> {
48 let result = BnKeystoreService::new_binder(Self {
49 sec_level: Asp::new({
50 let sec_level =
51 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
52 .context("While trying to create IKeystoreSecurityLevel")?;
53 sec_level.as_binder()
54 }),
55 });
56 result.as_binder().set_requesting_sid(true);
57 Ok(result)
58 }
59
60 fn get_security_level(
61 &self,
62 security_level: SecurityLevel,
63 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
64 match security_level {
65 SecurityLevel::TRUSTED_ENVIRONMENT => self
66 .sec_level
67 .get_interface()
68 .context("In get_security_level: Failed to get IKeystoreSecurityLevel."),
69 _ => Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
70 }
71 }
72
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070073 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -070074 let mut key_entry: KeyEntry = DB
75 .with(|db| {
76 db.borrow_mut().load_key_entry(
77 key.clone(),
78 KeyEntryLoadBits::PUBLIC,
79 ThreadState::get_calling_uid(),
80 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
81 )
82 })
83 .context("In get_key_entry, while trying to load key info.")?;
84
85 let i_sec_level = match key_entry.sec_level() {
86 SecurityLevel::TRUSTED_ENVIRONMENT => self
87 .sec_level
88 .get_interface()
89 .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
90 _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
91 };
92
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070093 Ok(KeyEntryResponse {
94 iSecurityLevel: Some(i_sec_level),
95 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -070096 key: KeyDescriptor {
97 domain: Domain::KEY_ID,
98 nspace: key_entry.id(),
99 ..Default::default()
100 },
Janis Danisevskis04b02832020-10-26 09:21:40 -0700101 keySecurityLevel: KsSecurityLevel(key_entry.sec_level().0),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700102 certificate: key_entry.take_cert(),
103 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskis04b02832020-10-26 09:21:40 -0700104 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700105 ..Default::default()
106 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700107 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700108 }
109
110 fn update_subcomponent(
111 &self,
112 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700113 public_cert: Option<&[u8]>,
114 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700115 ) -> Result<()> {
116 DB.with::<_, Result<()>>(|db| {
117 let mut db = db.borrow_mut();
118 let key_entry = db
119 .load_key_entry(
120 key.clone(),
121 KeyEntryLoadBits::NONE,
122 ThreadState::get_calling_uid(),
123 |k, av| {
124 check_key_permission(KeyPerm::update(), k, &av)
125 .context("In update_subcomponent.")
126 },
127 )
128 .context("Failed to load key_entry.")?;
129
130 if let Some(cert) = public_cert {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700131 db.insert_blob(key_entry.id(), SubComponentType::CERT, cert, key_entry.sec_level())
132 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700133 }
134
135 if let Some(cert_chain) = certificate_chain {
136 db.insert_blob(
137 key_entry.id(),
138 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700139 cert_chain,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700140 key_entry.sec_level(),
141 )
142 .context("Failed to update cert chain subcomponent.")?;
143 }
144 Ok(())
145 })
146 .context("In update_subcomponent.")
147 }
148
149 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
150 // TODO implement.
151 Err(anyhow!(error::Error::sys()))
152 }
153
154 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
155 // TODO implement.
156 Err(anyhow!(error::Error::sys()))
157 }
158
159 fn grant(
160 &self,
161 key: &KeyDescriptor,
162 grantee_uid: i32,
163 access_vector: permission::KeyPermSet,
164 ) -> Result<KeyDescriptor> {
165 DB.with(|db| {
166 db.borrow_mut().grant(
167 key.clone(),
168 ThreadState::get_calling_uid(),
169 grantee_uid as u32,
170 access_vector,
171 |k, av| check_grant_permission(*av, k).context("During grant."),
172 )
173 })
174 .context("In KeystoreService::grant.")
175 }
176
177 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
178 DB.with(|db| {
179 db.borrow_mut().ungrant(
180 key.clone(),
181 ThreadState::get_calling_uid(),
182 grantee_uid as u32,
183 |k| check_key_permission(KeyPerm::grant(), k, &None),
184 )
185 })
186 .context("In KeystoreService::ungrant.")
187 }
188}
189
190impl binder::Interface for KeystoreService {}
191
192// Implementation of IKeystoreService. See AIDL spec at
193// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
194impl IKeystoreService for KeystoreService {
195 fn getSecurityLevel(
196 &self,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700197 security_level: KsSecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700198 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
Janis Danisevskis04b02832020-10-26 09:21:40 -0700199 map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700200 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700201 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
202 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700203 }
204 fn updateSubcomponent(
205 &self,
206 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700207 public_cert: Option<&[u8]>,
208 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700209 ) -> binder::public_api::Result<()> {
210 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
211 }
212 fn listEntries(
213 &self,
214 domain: Domain,
215 namespace: i64,
216 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
217 map_or_log_err(self.list_entries(domain, namespace), Ok)
218 }
219 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
220 map_or_log_err(self.delete_key(key), Ok)
221 }
222 fn grant(
223 &self,
224 key: &KeyDescriptor,
225 grantee_uid: i32,
226 access_vector: i32,
227 ) -> binder::public_api::Result<KeyDescriptor> {
228 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
229 }
230 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
231 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
232 }
233}