blob: 82954ca66a5d6a9164f0b942efa42b4c6b415785 [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;
27use crate::utils::{check_grant_permission, check_key_permission, Asp};
28use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070029 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
30 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
31 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070032 SecurityLevel::SecurityLevel,
33};
34use anyhow::{anyhow, Context, Result};
35use binder::{IBinder, Interface, ThreadState};
36
37/// Implementation of the IKeystoreService.
38pub struct KeystoreService {
39 sec_level: Asp,
40}
41
42impl KeystoreService {
43 /// Create a new instance of the Keystore 2.0 service.
44 pub fn new_native_binder() -> Result<impl IKeystoreService> {
45 let result = BnKeystoreService::new_binder(Self {
46 sec_level: Asp::new({
47 let sec_level =
48 KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
49 .context("While trying to create IKeystoreSecurityLevel")?;
50 sec_level.as_binder()
51 }),
52 });
53 result.as_binder().set_requesting_sid(true);
54 Ok(result)
55 }
56
57 fn get_security_level(
58 &self,
59 security_level: SecurityLevel,
60 ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
61 match security_level {
62 SecurityLevel::TRUSTED_ENVIRONMENT => self
63 .sec_level
64 .get_interface()
65 .context("In get_security_level: Failed to get IKeystoreSecurityLevel."),
66 _ => Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
67 }
68 }
69
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070070 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -070071 let mut key_entry: KeyEntry = DB
72 .with(|db| {
73 db.borrow_mut().load_key_entry(
74 key.clone(),
75 KeyEntryLoadBits::PUBLIC,
76 ThreadState::get_calling_uid(),
77 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
78 )
79 })
80 .context("In get_key_entry, while trying to load key info.")?;
81
82 let i_sec_level = match key_entry.sec_level() {
83 SecurityLevel::TRUSTED_ENVIRONMENT => self
84 .sec_level
85 .get_interface()
86 .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
87 _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
88 };
89
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070090 Ok(KeyEntryResponse {
91 iSecurityLevel: Some(i_sec_level),
92 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -070093 key: KeyDescriptor {
94 domain: Domain::KEY_ID,
95 nspace: key_entry.id(),
96 ..Default::default()
97 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070098 keySecurityLevel: key_entry.sec_level(),
99 certificate: key_entry.take_cert(),
100 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700101 // TODO add key characteristics here.
102 ..Default::default()
103 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700104 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700105 }
106
107 fn update_subcomponent(
108 &self,
109 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700110 public_cert: Option<&[u8]>,
111 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700112 ) -> Result<()> {
113 DB.with::<_, Result<()>>(|db| {
114 let mut db = db.borrow_mut();
115 let key_entry = db
116 .load_key_entry(
117 key.clone(),
118 KeyEntryLoadBits::NONE,
119 ThreadState::get_calling_uid(),
120 |k, av| {
121 check_key_permission(KeyPerm::update(), k, &av)
122 .context("In update_subcomponent.")
123 },
124 )
125 .context("Failed to load key_entry.")?;
126
127 if let Some(cert) = public_cert {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700128 db.insert_blob(key_entry.id(), SubComponentType::CERT, cert, key_entry.sec_level())
129 .context("Failed to update cert subcomponent.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700130 }
131
132 if let Some(cert_chain) = certificate_chain {
133 db.insert_blob(
134 key_entry.id(),
135 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700136 cert_chain,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700137 key_entry.sec_level(),
138 )
139 .context("Failed to update cert chain subcomponent.")?;
140 }
141 Ok(())
142 })
143 .context("In update_subcomponent.")
144 }
145
146 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
147 // TODO implement.
148 Err(anyhow!(error::Error::sys()))
149 }
150
151 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
152 // TODO implement.
153 Err(anyhow!(error::Error::sys()))
154 }
155
156 fn grant(
157 &self,
158 key: &KeyDescriptor,
159 grantee_uid: i32,
160 access_vector: permission::KeyPermSet,
161 ) -> Result<KeyDescriptor> {
162 DB.with(|db| {
163 db.borrow_mut().grant(
164 key.clone(),
165 ThreadState::get_calling_uid(),
166 grantee_uid as u32,
167 access_vector,
168 |k, av| check_grant_permission(*av, k).context("During grant."),
169 )
170 })
171 .context("In KeystoreService::grant.")
172 }
173
174 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
175 DB.with(|db| {
176 db.borrow_mut().ungrant(
177 key.clone(),
178 ThreadState::get_calling_uid(),
179 grantee_uid as u32,
180 |k| check_key_permission(KeyPerm::grant(), k, &None),
181 )
182 })
183 .context("In KeystoreService::ungrant.")
184 }
185}
186
187impl binder::Interface for KeystoreService {}
188
189// Implementation of IKeystoreService. See AIDL spec at
190// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
191impl IKeystoreService for KeystoreService {
192 fn getSecurityLevel(
193 &self,
194 security_level: SecurityLevel,
195 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
196 map_or_log_err(self.get_security_level(security_level), Ok)
197 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700198 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
199 map_or_log_err(self.get_key_entry(key), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700200 }
201 fn updateSubcomponent(
202 &self,
203 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700204 public_cert: Option<&[u8]>,
205 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700206 ) -> binder::public_api::Result<()> {
207 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
208 }
209 fn listEntries(
210 &self,
211 domain: Domain,
212 namespace: i64,
213 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
214 map_or_log_err(self.list_entries(domain, namespace), Ok)
215 }
216 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
217 map_or_log_err(self.delete_key(key), Ok)
218 }
219 fn grant(
220 &self,
221 key: &KeyDescriptor,
222 grantee_uid: i32,
223 access_vector: i32,
224 ) -> binder::public_api::Result<KeyDescriptor> {
225 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
226 }
227 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
228 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
229 }
230}