blob: ea17766a73134f6a8e8d2ec6457e5409673a39ae [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::{
29 Certificate::Certificate, CertificateChain::CertificateChain, Domain::Domain,
30 IKeystoreSecurityLevel::IKeystoreSecurityLevel, IKeystoreService::BnKeystoreService,
31 IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
32 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
70 fn get_key_entry(
71 &self,
72 key: &KeyDescriptor,
73 ) -> Result<(
74 KeyMetadata,
75 Option<Certificate>,
76 Option<CertificateChain>,
77 Box<dyn IKeystoreSecurityLevel>,
78 )> {
79 let mut key_entry: KeyEntry = DB
80 .with(|db| {
81 db.borrow_mut().load_key_entry(
82 key.clone(),
83 KeyEntryLoadBits::PUBLIC,
84 ThreadState::get_calling_uid(),
85 |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
86 )
87 })
88 .context("In get_key_entry, while trying to load key info.")?;
89
90 let i_sec_level = match key_entry.sec_level() {
91 SecurityLevel::TRUSTED_ENVIRONMENT => self
92 .sec_level
93 .get_interface()
94 .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
95 _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
96 };
97
98 Ok((
99 KeyMetadata {
100 key: KeyDescriptor {
101 domain: Domain::KEY_ID,
102 nspace: key_entry.id(),
103 ..Default::default()
104 },
105 securityLevel: key_entry.sec_level(),
106 // TODO add key characteristics here.
107 ..Default::default()
108 },
109 key_entry.take_cert().map(|v| Certificate { data: v }),
110 key_entry.take_cert_chain().map(|v| CertificateChain { data: v }),
111 i_sec_level,
112 ))
113 }
114
115 fn update_subcomponent(
116 &self,
117 key: &KeyDescriptor,
118 public_cert: Option<&Certificate>,
119 certificate_chain: Option<&CertificateChain>,
120 ) -> Result<()> {
121 DB.with::<_, Result<()>>(|db| {
122 let mut db = db.borrow_mut();
123 let key_entry = db
124 .load_key_entry(
125 key.clone(),
126 KeyEntryLoadBits::NONE,
127 ThreadState::get_calling_uid(),
128 |k, av| {
129 check_key_permission(KeyPerm::update(), k, &av)
130 .context("In update_subcomponent.")
131 },
132 )
133 .context("Failed to load key_entry.")?;
134
135 if let Some(cert) = public_cert {
136 db.insert_blob(
137 key_entry.id(),
138 SubComponentType::CERT,
139 &cert.data,
140 key_entry.sec_level(),
141 )
142 .context("Failed to update cert subcomponent.")?;
143 }
144
145 if let Some(cert_chain) = certificate_chain {
146 db.insert_blob(
147 key_entry.id(),
148 SubComponentType::CERT_CHAIN,
149 &cert_chain.data,
150 key_entry.sec_level(),
151 )
152 .context("Failed to update cert chain subcomponent.")?;
153 }
154 Ok(())
155 })
156 .context("In update_subcomponent.")
157 }
158
159 fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
160 // TODO implement.
161 Err(anyhow!(error::Error::sys()))
162 }
163
164 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
165 // TODO implement.
166 Err(anyhow!(error::Error::sys()))
167 }
168
169 fn grant(
170 &self,
171 key: &KeyDescriptor,
172 grantee_uid: i32,
173 access_vector: permission::KeyPermSet,
174 ) -> Result<KeyDescriptor> {
175 DB.with(|db| {
176 db.borrow_mut().grant(
177 key.clone(),
178 ThreadState::get_calling_uid(),
179 grantee_uid as u32,
180 access_vector,
181 |k, av| check_grant_permission(*av, k).context("During grant."),
182 )
183 })
184 .context("In KeystoreService::grant.")
185 }
186
187 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
188 DB.with(|db| {
189 db.borrow_mut().ungrant(
190 key.clone(),
191 ThreadState::get_calling_uid(),
192 grantee_uid as u32,
193 |k| check_key_permission(KeyPerm::grant(), k, &None),
194 )
195 })
196 .context("In KeystoreService::ungrant.")
197 }
198}
199
200impl binder::Interface for KeystoreService {}
201
202// Implementation of IKeystoreService. See AIDL spec at
203// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
204impl IKeystoreService for KeystoreService {
205 fn getSecurityLevel(
206 &self,
207 security_level: SecurityLevel,
208 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
209 map_or_log_err(self.get_security_level(security_level), Ok)
210 }
211 fn getKeyEntry(
212 &self,
213 key: &KeyDescriptor,
214 metadata: &mut KeyMetadata,
215 public_cert: &mut Option<Certificate>,
216 certificate_chain: &mut Option<CertificateChain>,
217 ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
218 map_or_log_err(self.get_key_entry(key), |v| {
219 *metadata = v.0;
220 *public_cert = v.1;
221 *certificate_chain = v.2;
222 Ok(v.3)
223 })
224 }
225 fn updateSubcomponent(
226 &self,
227 key: &KeyDescriptor,
228 public_cert: Option<&Certificate>,
229 certificate_chain: Option<&CertificateChain>,
230 ) -> binder::public_api::Result<()> {
231 map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
232 }
233 fn listEntries(
234 &self,
235 domain: Domain,
236 namespace: i64,
237 ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
238 map_or_log_err(self.list_entries(domain, namespace), Ok)
239 }
240 fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
241 map_or_log_err(self.delete_key(key), Ok)
242 }
243 fn grant(
244 &self,
245 key: &KeyDescriptor,
246 grantee_uid: i32,
247 access_vector: i32,
248 ) -> binder::public_api::Result<KeyDescriptor> {
249 map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
250 }
251 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
252 map_or_log_err(self.ungrant(key, grantee_uid), Ok)
253 }
254}