1 // Copyright 2022, 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 use crate::keystore2_client_test_utils::{
16 generate_ec_key_and_grant_to_users, perform_sample_sign_operation,
17 };
18 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
19 Digest::Digest, KeyPurpose::KeyPurpose,
20 };
21 use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::IKeystoreMaintenance;
22 use android_system_keystore2::aidl::android::system::keystore2::{
23 Domain::Domain, IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor,
24 KeyEntryResponse::KeyEntryResponse, KeyPermission::KeyPermission, ResponseCode::ResponseCode,
25 };
26 use keystore2_test_utils::{
27 authorizations, get_keystore_service, key_generations,
28 key_generations::{map_ks_error, Error},
29 run_as, SecLevel,
30 };
31 use nix::unistd::getuid;
32 use rustutils::users::AID_USER_OFFSET;
33
34 static USER_MANAGER_SERVICE_NAME: &str = "android.security.maintenance";
35
36 /// Produce a [`KeyDescriptor`] for a granted key.
granted_key_descriptor(nspace: i64) -> KeyDescriptor37 fn granted_key_descriptor(nspace: i64) -> KeyDescriptor {
38 KeyDescriptor { domain: Domain::GRANT, nspace, alias: None, blob: None }
39 }
40
get_granted_key( ks2: &binder::Strong<dyn IKeystoreService>, nspace: i64, ) -> Result<KeyEntryResponse, Error>41 fn get_granted_key(
42 ks2: &binder::Strong<dyn IKeystoreService>,
43 nspace: i64,
44 ) -> Result<KeyEntryResponse, Error> {
45 map_ks_error(ks2.getKeyEntry(&granted_key_descriptor(nspace)))
46 }
47
48 /// Generate an EC signing key in the SELINUX domain and grant it to the user with given access
49 /// vector.
generate_and_grant_selinux_key( grantee_uid: u32, access_vector: i32, ) -> Result<KeyDescriptor, Error>50 fn generate_and_grant_selinux_key(
51 grantee_uid: u32,
52 access_vector: i32,
53 ) -> Result<KeyDescriptor, Error> {
54 let sl = SecLevel::tee();
55 let alias = format!("{}{}", "ks_grant_test_key_1", getuid());
56
57 let key_metadata = key_generations::generate_ec_p256_signing_key(
58 &sl,
59 Domain::SELINUX,
60 key_generations::SELINUX_SHELL_NAMESPACE,
61 Some(alias),
62 None,
63 )
64 .unwrap();
65
66 map_ks_error(sl.keystore2.grant(
67 &key_metadata.key,
68 grantee_uid.try_into().unwrap(),
69 access_vector,
70 ))
71 }
72
73 /// Use a granted key to perform a signing operation.
sign_with_granted_key(grant_key_nspace: i64) -> Result<(), Error>74 fn sign_with_granted_key(grant_key_nspace: i64) -> Result<(), Error> {
75 let sl = SecLevel::tee();
76 let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)?;
77
78 // Perform sample crypto operation using granted key.
79 let op_response = map_ks_error(sl.binder.createOperation(
80 &key_entry_response.metadata.key,
81 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
82 false,
83 ))?;
84
85 assert!(op_response.iOperation.is_some());
86 assert_eq!(
87 Ok(()),
88 map_ks_error(perform_sample_sign_operation(&op_response.iOperation.unwrap()))
89 );
90
91 Ok(())
92 }
93
get_maintenance() -> binder::Strong<dyn IKeystoreMaintenance>94 fn get_maintenance() -> binder::Strong<dyn IKeystoreMaintenance> {
95 binder::get_interface(USER_MANAGER_SERVICE_NAME).unwrap()
96 }
97
98 /// Try to grant an SELINUX key with permission that does not map to any of the `KeyPermission`
99 /// values. An error is expected with values that does not map to set of permissions listed in
100 /// `KeyPermission`.
101 #[test]
grant_selinux_key_with_invalid_perm()102 fn grant_selinux_key_with_invalid_perm() {
103 const USER_ID: u32 = 99;
104 const APPLICATION_ID: u32 = 10001;
105 let grantee_uid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
106 let invalid_access_vector = KeyPermission::CONVERT_STORAGE_KEY_TO_EPHEMERAL.0 << 19;
107
108 let result = generate_and_grant_selinux_key(grantee_uid, invalid_access_vector);
109 assert!(result.is_err());
110 assert_eq!(Error::Rc(ResponseCode::SYSTEM_ERROR), result.unwrap_err());
111 }
112
113 /// Try to grant an SELINUX key with empty access vector `KeyPermission::NONE`, should be able to
114 /// grant a key with empty access vector successfully. In grantee context try to use the granted
115 /// key, it should fail to load the key with permission denied error.
116 #[test]
grant_selinux_key_with_perm_none()117 fn grant_selinux_key_with_perm_none() {
118 const USER_ID: u32 = 99;
119 const APPLICATION_ID: u32 = 10001;
120 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
121 static GRANTEE_GID: u32 = GRANTEE_UID;
122
123 let grantor_fn = || {
124 let empty_access_vector = KeyPermission::NONE.0;
125
126 let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, empty_access_vector).unwrap();
127
128 assert_eq!(grant_key.domain, Domain::GRANT);
129
130 grant_key.nspace
131 };
132
133 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
134 // `--test-threads=1`), and nothing yet done with binder.
135 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
136
137 // In grantee context try to load the key, it should fail to load the granted key as it is
138 // granted with empty access vector.
139 let grantee_fn = move || {
140 let keystore2 = get_keystore_service();
141
142 let result = get_granted_key(&keystore2, grant_key_nspace);
143 assert!(result.is_err());
144 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
145 };
146
147 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
148 // `--test-threads=1`), and nothing yet done with binder.
149 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
150 }
151
152 /// Grant an SELINUX key to the user (grantee) with `GET_INFO|USE` key permissions. Verify whether
153 /// grantee can succeed in loading the granted key and try to perform simple operation using this
154 /// granted key. Grantee should be able to load the key and use the key to perform crypto operation
155 /// successfully. Try to delete the granted key in grantee context where it is expected to fail to
156 /// delete it as `DELETE` permission is not granted.
157 #[test]
grant_selinux_key_get_info_use_perms()158 fn grant_selinux_key_get_info_use_perms() {
159 const USER_ID: u32 = 99;
160 const APPLICATION_ID: u32 = 10001;
161 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
162 static GRANTEE_GID: u32 = GRANTEE_UID;
163
164 // Generate a key and grant it to a user with GET_INFO|USE key permissions.
165 let grantor_fn = || {
166 let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
167 let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, access_vector).unwrap();
168
169 assert_eq!(grant_key.domain, Domain::GRANT);
170
171 grant_key.nspace
172 };
173
174 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
175 // `--test-threads=1`), and nothing yet done with binder.
176 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
177
178 // In grantee context load the key and try to perform crypto operation.
179 let grantee_fn = move || {
180 let sl = SecLevel::tee();
181
182 // Load the granted key.
183 let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace).unwrap();
184
185 // Perform sample crypto operation using granted key.
186 let op_response = sl
187 .binder
188 .createOperation(
189 &key_entry_response.metadata.key,
190 &authorizations::AuthSetBuilder::new()
191 .purpose(KeyPurpose::SIGN)
192 .digest(Digest::SHA_2_256),
193 false,
194 )
195 .unwrap();
196 assert!(op_response.iOperation.is_some());
197 assert_eq!(
198 Ok(()),
199 map_ks_error(perform_sample_sign_operation(&op_response.iOperation.unwrap()))
200 );
201
202 // Try to delete the key, it is expected to be fail with permission denied error.
203 let result =
204 map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
205 assert!(result.is_err());
206 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
207 };
208
209 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
210 // `--test-threads=1`), and nothing yet done with binder.
211 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
212 }
213
214 /// Grant an SELINUX key to the user (grantee) with just `GET_INFO` key permissions. Verify whether
215 /// grantee can succeed in loading the granted key and try to perform simple operation using this
216 /// granted key.
217 #[test]
grant_selinux_key_get_info_only()218 fn grant_selinux_key_get_info_only() {
219 const USER_ID: u32 = 99;
220 const APPLICATION_ID: u32 = 10001;
221 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
222 static GRANTEE_GID: u32 = GRANTEE_UID;
223
224 // Generate a key and grant it to a user with (just) GET_INFO key permissions.
225 let grantor_fn = || {
226 let access_vector = KeyPermission::GET_INFO.0;
227 let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, access_vector).unwrap();
228
229 assert_eq!(grant_key.domain, Domain::GRANT);
230
231 grant_key.nspace
232 };
233
234 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
235 // `--test-threads=1`), and nothing yet done with binder on the main thread.
236 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
237
238 // In grantee context load the key and try to perform crypto operation.
239 let grantee_fn = move || {
240 let sl = SecLevel::tee();
241
242 // Load the granted key.
243 let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)
244 .expect("failed to get info for granted key");
245
246 // Attempt to perform sample crypto operation using granted key, now identified by <KEY_ID,
247 // key_id>.
248 let result = map_ks_error(
249 sl.binder.createOperation(
250 &key_entry_response.metadata.key,
251 &authorizations::AuthSetBuilder::new()
252 .purpose(KeyPurpose::SIGN)
253 .digest(Digest::SHA_2_256),
254 false,
255 ),
256 );
257 assert!(result.is_err());
258 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
259
260 // Try to delete the key using a <GRANT, grant_id> descriptor.
261 let result =
262 map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
263 assert!(result.is_err());
264 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
265
266 // Try to delete the key using a <KEY_ID, key_id> descriptor.
267 let result = map_ks_error(sl.keystore2.deleteKey(&key_entry_response.metadata.key));
268 assert!(result.is_err());
269 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
270 };
271
272 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
273 // `--test-threads=1`), and nothing yet done with binder on the main thread.
274 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
275 }
276
277 /// Grant an APP key to the user (grantee) with just `GET_INFO` key permissions. Verify whether
278 /// grantee can succeed in loading the granted key and try to perform simple operation using this
279 /// granted key.
280 #[test]
grant_app_key_get_info_only()281 fn grant_app_key_get_info_only() {
282 const USER_ID: u32 = 99;
283 const APPLICATION_ID: u32 = 10001;
284 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
285 static GRANTEE_GID: u32 = GRANTEE_UID;
286 static ALIAS: &str = "ks_grant_key_info_only";
287
288 // Generate a key and grant it to a user with (just) GET_INFO key permissions.
289 let grantor_fn = || {
290 let sl = SecLevel::tee();
291 let access_vector = KeyPermission::GET_INFO.0;
292 let mut grant_keys = generate_ec_key_and_grant_to_users(
293 &sl,
294 Some(ALIAS.to_string()),
295 vec![GRANTEE_UID.try_into().unwrap()],
296 access_vector,
297 )
298 .unwrap();
299
300 grant_keys.remove(0)
301 };
302
303 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
304 // `--test-threads=1`), and nothing yet done with binder on the main thread.
305 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
306
307 // In grantee context load the key and try to perform crypto operation.
308 let grantee_fn = move || {
309 let sl = SecLevel::tee();
310
311 // Load the granted key.
312 let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)
313 .expect("failed to get info for granted key");
314
315 // Attempt to perform sample crypto operation using granted key, now identified by <KEY_ID,
316 // key_id>.
317 let result = map_ks_error(
318 sl.binder.createOperation(
319 &key_entry_response.metadata.key,
320 &authorizations::AuthSetBuilder::new()
321 .purpose(KeyPurpose::SIGN)
322 .digest(Digest::SHA_2_256),
323 false,
324 ),
325 );
326 assert!(result.is_err());
327 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
328
329 // Try to delete the key using a <GRANT, grant_id> descriptor.
330 let result =
331 map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
332 assert!(result.is_err());
333 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
334
335 // Try to delete the key using a <KEY_ID, key_id> descriptor.
336 let result = map_ks_error(sl.keystore2.deleteKey(&key_entry_response.metadata.key));
337 assert!(result.is_err());
338 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
339 };
340
341 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
342 // `--test-threads=1`), and nothing yet done with binder on the main thread.
343 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
344 }
345
346 /// Grant an APP key to the user with DELETE access. In grantee context load the key and delete it.
347 /// Verify that grantee should succeed in deleting the granted key and in grantor context test
348 /// should fail to find the key with error response `KEY_NOT_FOUND`.
349 #[test]
grant_app_key_delete_success()350 fn grant_app_key_delete_success() {
351 const USER_ID: u32 = 99;
352 const APPLICATION_ID: u32 = 10001;
353 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
354 static GRANTEE_GID: u32 = GRANTEE_UID;
355 static ALIAS: &str = "ks_grant_key_delete_success";
356
357 // Generate a key and grant it to a user with DELETE permission.
358 let grantor_fn = || {
359 let sl = SecLevel::tee();
360 let access_vector = KeyPermission::DELETE.0;
361 let mut grant_keys = generate_ec_key_and_grant_to_users(
362 &sl,
363 Some(ALIAS.to_string()),
364 vec![GRANTEE_UID.try_into().unwrap()],
365 access_vector,
366 )
367 .unwrap();
368
369 grant_keys.remove(0)
370 };
371
372 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
373 // `--test-threads=1`), and nothing yet done with binder.
374 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
375
376 // Grantee context, delete the key.
377 let grantee_fn = move || {
378 let keystore2 = get_keystore_service();
379 keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)).unwrap();
380 };
381
382 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
383 // `--test-threads=1`), and nothing yet done with binder.
384 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
385
386 // Verify whether key got deleted in grantor's context.
387 let grantor_fn = move || {
388 let keystore2_inst = get_keystore_service();
389 let result = map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
390 domain: Domain::APP,
391 nspace: -1,
392 alias: Some(ALIAS.to_string()),
393 blob: None,
394 }));
395 assert!(result.is_err());
396 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
397 };
398
399 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
400 // `--test-threads=1`), and nothing yet done with binder.
401 unsafe { run_as::run_as_root(grantor_fn) };
402 }
403
404 /// Grant an APP key to the user. In grantee context load the granted key and try to grant it to
405 /// second user. Test should fail with a response code `PERMISSION_DENIED` to grant a key to second
406 /// user from grantee context. Test should make sure second grantee should not have a access to
407 /// granted key.
408 #[test]
grant_granted_app_key_fails()409 fn grant_granted_app_key_fails() {
410 const GRANTOR_USER_ID: u32 = 97;
411 const GRANTOR_APPLICATION_ID: u32 = 10003;
412 static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
413 static GRANTOR_GID: u32 = GRANTOR_UID;
414
415 const USER_ID: u32 = 99;
416 const APPLICATION_ID: u32 = 10001;
417 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
418 static GRANTEE_GID: u32 = GRANTEE_UID;
419
420 const SEC_USER_ID: u32 = 98;
421 const SEC_APPLICATION_ID: u32 = 10001;
422 static SEC_GRANTEE_UID: u32 = SEC_USER_ID * AID_USER_OFFSET + SEC_APPLICATION_ID;
423 static SEC_GRANTEE_GID: u32 = SEC_GRANTEE_UID;
424
425 // Generate a key and grant it to a user with GET_INFO permission.
426 let grantor_fn = || {
427 let sl = SecLevel::tee();
428 let access_vector = KeyPermission::GET_INFO.0;
429 let alias = format!("ks_grant_perm_denied_key_{}", getuid());
430 let mut grant_keys = generate_ec_key_and_grant_to_users(
431 &sl,
432 Some(alias),
433 vec![GRANTEE_UID.try_into().unwrap()],
434 access_vector,
435 )
436 .unwrap();
437
438 grant_keys.remove(0)
439 };
440 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
441 // `--test-threads=1`), and nothing yet done with binder.
442 let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
443
444 // Grantee context, load the granted key and try to grant it to `SEC_GRANTEE_UID` grantee.
445 let grantee_fn = move || {
446 let keystore2 = get_keystore_service();
447 let access_vector = KeyPermission::GET_INFO.0;
448
449 // Try to grant when identifying the key with <GRANT, grant_nspace>.
450 let result = map_ks_error(keystore2.grant(
451 &granted_key_descriptor(grant_key_nspace),
452 SEC_GRANTEE_UID.try_into().unwrap(),
453 access_vector,
454 ));
455 assert!(result.is_err());
456 assert_eq!(Error::Rc(ResponseCode::SYSTEM_ERROR), result.unwrap_err());
457
458 // Load the key info and try to grant when identifying the key with <KEY_ID, keyid>.
459 let key_entry_response = get_granted_key(&keystore2, grant_key_nspace).unwrap();
460 let result = map_ks_error(keystore2.grant(
461 &key_entry_response.metadata.key,
462 SEC_GRANTEE_UID.try_into().unwrap(),
463 access_vector,
464 ));
465 assert!(result.is_err());
466 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
467 };
468
469 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
470 // `--test-threads=1`), and nothing yet done with binder.
471 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
472
473 // Make sure second grantee shouldn't have access to the above granted key.
474 let grantee2_fn = move || {
475 let keystore2 = get_keystore_service();
476 let result = get_granted_key(&keystore2, grant_key_nspace);
477 assert!(result.is_err());
478 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
479 };
480
481 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
482 // `--test-threads=1`), and nothing yet done with binder.
483 unsafe { run_as::run_as_app(SEC_GRANTEE_UID, SEC_GRANTEE_GID, grantee2_fn) };
484 }
485
486 /// Grant an APP key to one user, from a normal user. Check that grantee context can load the
487 /// granted key, but that a second unrelated context cannot.
488 #[test]
grant_app_key_only_to_grantee()489 fn grant_app_key_only_to_grantee() {
490 const GRANTOR_USER_ID: u32 = 97;
491 const GRANTOR_APPLICATION_ID: u32 = 10003;
492 static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
493 static GRANTOR_GID: u32 = GRANTOR_UID;
494
495 const USER_ID: u32 = 99;
496 const APPLICATION_ID: u32 = 10001;
497 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
498 static GRANTEE_GID: u32 = GRANTEE_UID;
499
500 const SEC_USER_ID: u32 = 98;
501 const SEC_APPLICATION_ID: u32 = 10001;
502 static SEC_GRANTEE_UID: u32 = SEC_USER_ID * AID_USER_OFFSET + SEC_APPLICATION_ID;
503 static SEC_GRANTEE_GID: u32 = SEC_GRANTEE_UID;
504
505 // Child function to generate a key and grant it to a user with `GET_INFO` permission.
506 let grantor_fn = || {
507 let sl = SecLevel::tee();
508 let access_vector = KeyPermission::GET_INFO.0;
509 let alias = format!("ks_grant_single_{}", getuid());
510 let mut grant_keys = generate_ec_key_and_grant_to_users(
511 &sl,
512 Some(alias),
513 vec![GRANTEE_UID.try_into().unwrap()],
514 access_vector,
515 )
516 .unwrap();
517
518 grant_keys.remove(0)
519 };
520
521 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
522 // `--test-threads=1`), and nothing yet done with binder on the main thread.
523 let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
524
525 // Child function for the grantee context: can load the granted key.
526 let grantee_fn = move || {
527 let keystore2 = get_keystore_service();
528 let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
529
530 // Return the underlying key ID to simulate an ID leak.
531 assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
532 rsp.metadata.key.nspace
533 };
534
535 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
536 // `--test-threads=1`), and nothing yet done with binder on the main thread.
537 let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
538
539 // Second context does not have access to the above granted key, because it's identified
540 // by <uid, grant_nspace> and the implicit uid value is different. Also, even if the
541 // second context gets hold of the key ID somehow, that also doesn't work.
542 let non_grantee_fn = move || {
543 let keystore2 = get_keystore_service();
544 let result = get_granted_key(&keystore2, grant_key_nspace);
545 assert!(result.is_err());
546 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
547
548 let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
549 domain: Domain::KEY_ID,
550 nspace: key_id,
551 alias: None,
552 blob: None,
553 }));
554 assert!(result.is_err());
555 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
556 };
557
558 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
559 // `--test-threads=1`), and nothing yet done with binder on the main thread.
560 unsafe { run_as::run_as_app(SEC_GRANTEE_UID, SEC_GRANTEE_GID, non_grantee_fn) };
561 }
562
563 /// Try to grant an APP key with `GRANT` access. Keystore2 system shouldn't allow to grant a key
564 /// with `GRANT` access. Test should fail to grant a key with `PERMISSION_DENIED` error response
565 /// code.
566 #[test]
grant_app_key_with_grant_perm_fails()567 fn grant_app_key_with_grant_perm_fails() {
568 let sl = SecLevel::tee();
569 let access_vector = KeyPermission::GRANT.0;
570 let alias = format!("ks_grant_access_vec_key_{}", getuid());
571 let user_id = 98;
572 let application_id = 10001;
573 let grantee_uid = user_id * AID_USER_OFFSET + application_id;
574
575 let result = map_ks_error(generate_ec_key_and_grant_to_users(
576 &sl,
577 Some(alias),
578 vec![grantee_uid.try_into().unwrap()],
579 access_vector,
580 ));
581 assert!(result.is_err());
582 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
583 }
584
585 /// Try to grant a non-existing SELINUX key to the user. Test should fail with `KEY_NOT_FOUND` error
586 /// response.
587 #[test]
grant_fails_with_non_existing_selinux_key()588 fn grant_fails_with_non_existing_selinux_key() {
589 let keystore2 = get_keystore_service();
590 let alias = format!("ks_grant_test_non_existing_key_5_{}", getuid());
591 let user_id = 98;
592 let application_id = 10001;
593 let grantee_uid = user_id * AID_USER_OFFSET + application_id;
594 let access_vector = KeyPermission::GET_INFO.0;
595
596 let result = map_ks_error(keystore2.grant(
597 &KeyDescriptor {
598 domain: Domain::SELINUX,
599 nspace: key_generations::SELINUX_SHELL_NAMESPACE,
600 alias: Some(alias),
601 blob: None,
602 },
603 grantee_uid.try_into().unwrap(),
604 access_vector,
605 ));
606 assert!(result.is_err());
607 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
608 }
609
610 /// Grant a key to a UID (user ID A + app B) then uninstall user ID A. Initialize a new user with
611 /// the same user ID as the now-removed user. Check that app B for the new user can't load the key.
612 #[test]
grant_removed_when_grantee_user_id_removed()613 fn grant_removed_when_grantee_user_id_removed() {
614 const GRANTOR_USER_ID: u32 = 97;
615 const GRANTOR_APPLICATION_ID: u32 = 10003;
616 static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
617 static GRANTOR_GID: u32 = GRANTOR_UID;
618
619 const GRANTEE_USER_ID: u32 = 99;
620 const GRANTEE_APPLICATION_ID: u32 = 10001;
621 static GRANTEE_UID: u32 = GRANTEE_USER_ID * AID_USER_OFFSET + GRANTEE_APPLICATION_ID;
622 static GRANTEE_GID: u32 = GRANTEE_UID;
623
624 // Add a new user.
625 let create_grantee_user_id_fn = || {
626 let maint = get_maintenance();
627 maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
628 };
629
630 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
631 // `--test-threads=1`), and nothing yet done with binder on the main thread.
632 unsafe { run_as::run_as_root(create_grantee_user_id_fn) };
633
634 // Child function to generate a key and grant it to GRANTEE_UID with `GET_INFO` permission.
635 let grantor_fn = || {
636 let sl = SecLevel::tee();
637 let access_vector = KeyPermission::GET_INFO.0;
638 let alias = format!("ks_grant_single_{}", getuid());
639 let mut grant_keys = generate_ec_key_and_grant_to_users(
640 &sl,
641 Some(alias),
642 vec![GRANTEE_UID.try_into().unwrap()],
643 access_vector,
644 )
645 .unwrap();
646
647 grant_keys.remove(0)
648 };
649
650 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
651 // `--test-threads=1`), and nothing yet done with binder on the main thread.
652 let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
653
654 // Child function for the grantee context: can load the granted key.
655 let grantee_fn = move || {
656 let keystore2 = get_keystore_service();
657 let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
658
659 // Return the underlying key ID to simulate an ID leak.
660 assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
661 rsp.metadata.key.nspace
662 };
663
664 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
665 // `--test-threads=1`), and nothing yet done with binder on the main thread.
666 let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
667
668 // Remove the grantee user and create a new user with the same user ID.
669 let overwrite_grantee_user_id_fn = || {
670 let maint = get_maintenance();
671 maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
672 maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
673 };
674
675 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
676 // `--test-threads=1`), and nothing yet done with binder on the main thread.
677 unsafe { run_as::run_as_root(overwrite_grantee_user_id_fn) };
678
679 // Second context identified by <uid, grant_nspace> (where uid is the same because the
680 // now-deleted and newly-created grantee users have the same user ID) does not have access to
681 // the above granted key.
682 let new_grantee_fn = move || {
683 // Check that the key cannot be accessed via grant (i.e. KeyDescriptor with Domain::GRANT).
684 let keystore2 = get_keystore_service();
685 let result = get_granted_key(&keystore2, grant_key_nspace);
686 assert!(result.is_err());
687 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
688
689 // Check that the key also cannot be accessed via key ID (i.e. KeyDescriptor with
690 // Domain::KEY_ID) if the second context somehow gets a hold of it.
691 let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
692 domain: Domain::KEY_ID,
693 nspace: key_id,
694 alias: None,
695 blob: None,
696 }));
697 assert!(result.is_err());
698 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
699 };
700
701 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
702 // `--test-threads=1`), and nothing yet done with binder on the main thread.
703 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, new_grantee_fn) };
704
705 // Clean up: remove grantee user.
706 let remove_grantee_user_id_fn = || {
707 let maint = get_maintenance();
708 maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
709 };
710
711 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
712 // `--test-threads=1`), and nothing yet done with binder on the main thread.
713 unsafe { run_as::run_as_root(remove_grantee_user_id_fn) };
714 }
715
716 /// Grant a key to a UID (user ID A + app B) then clear the namespace for user ID A + app B. Check
717 /// that the key can't be loaded by that UID (which would be the UID used if another app were to be
718 /// installed for user ID A with the same application ID B).
719 #[test]
grant_removed_when_grantee_app_uninstalled()720 fn grant_removed_when_grantee_app_uninstalled() {
721 const GRANTOR_USER_ID: u32 = 97;
722 const GRANTOR_APPLICATION_ID: u32 = 10003;
723 static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
724 static GRANTOR_GID: u32 = GRANTOR_UID;
725
726 const GRANTEE_USER_ID: u32 = 99;
727 const GRANTEE_APPLICATION_ID: u32 = 10001;
728 static GRANTEE_UID: u32 = GRANTEE_USER_ID * AID_USER_OFFSET + GRANTEE_APPLICATION_ID;
729 static GRANTEE_GID: u32 = GRANTEE_UID;
730
731 // Add a new user.
732 let create_grantee_user_id_fn = || {
733 let maint = get_maintenance();
734 maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
735 };
736
737 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
738 // `--test-threads=1`), and nothing yet done with binder on the main thread.
739 unsafe { run_as::run_as_root(create_grantee_user_id_fn) };
740
741 // Child function to generate a key and grant it to GRANTEE_UID with `GET_INFO` permission.
742 let grantor_fn = || {
743 let sl = SecLevel::tee();
744 let access_vector = KeyPermission::GET_INFO.0;
745 let alias = format!("ks_grant_single_{}", getuid());
746 let mut grant_keys = generate_ec_key_and_grant_to_users(
747 &sl,
748 Some(alias),
749 vec![GRANTEE_UID.try_into().unwrap()],
750 access_vector,
751 )
752 .unwrap();
753
754 grant_keys.remove(0)
755 };
756
757 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
758 // `--test-threads=1`), and nothing yet done with binder on the main thread.
759 let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
760
761 // Child function for the grantee context: can load the granted key.
762 let grantee_fn = move || {
763 let keystore2 = get_keystore_service();
764 let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
765
766 // Return the underlying key ID to simulate an ID leak.
767 assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
768 rsp.metadata.key.nspace
769 };
770
771 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
772 // `--test-threads=1`), and nothing yet done with binder on the main thread.
773 let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
774
775 // Clear the app's namespace, which is what happens when an app is uninstalled. Exercising the
776 // full app uninstallation "flow" isn't possible from a Keystore VTS test since we'd need to
777 // exercise the Java code that calls into the Keystore service. So, we can only test the
778 // entrypoint that we know gets triggered during app uninstallation based on the code's control
779 // flow.
780 let clear_grantee_uid_namespace_fn = || {
781 let maint = get_maintenance();
782 maint
783 .clearNamespace(Domain::APP, GRANTEE_UID.try_into().unwrap())
784 .expect("failed to clear namespace");
785 };
786
787 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
788 // `--test-threads=1`), and nothing yet done with binder on the main thread.
789 unsafe { run_as::run_as_root(clear_grantee_uid_namespace_fn) };
790
791 // The same context identified by <uid, grant_nspace> not longer has access to the above granted
792 // key. This would be the context if a new app were installed and assigned the same app ID.
793 let new_grantee_fn = move || {
794 // Check that the key cannot be accessed via grant (i.e. KeyDescriptor with Domain::GRANT).
795 let keystore2 = get_keystore_service();
796 let result = get_granted_key(&keystore2, grant_key_nspace);
797 assert!(result.is_err());
798 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
799
800 // Check that the key also cannot be accessed via key ID (i.e. KeyDescriptor with
801 // Domain::KEY_ID) if the second context somehow gets a hold of it.
802 let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
803 domain: Domain::KEY_ID,
804 nspace: key_id,
805 alias: None,
806 blob: None,
807 }));
808 assert!(result.is_err());
809 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
810 };
811
812 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
813 // `--test-threads=1`), and nothing yet done with binder on the main thread.
814 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, new_grantee_fn) };
815
816 // Clean up: remove grantee user.
817 let remove_grantee_user_id_fn = || {
818 let maint = get_maintenance();
819 maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
820 };
821
822 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
823 // `--test-threads=1`), and nothing yet done with binder on the main thread.
824 unsafe { run_as::run_as_root(remove_grantee_user_id_fn) };
825 }
826
827 /// Grant an APP key to the user and immediately ungrant the granted key. In grantee context try to load
828 /// the key. Grantee should fail to load the ungranted key with `KEY_NOT_FOUND` error response.
829 #[test]
ungrant_app_key_success()830 fn ungrant_app_key_success() {
831 const USER_ID: u32 = 99;
832 const APPLICATION_ID: u32 = 10001;
833 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
834 static GRANTEE_GID: u32 = GRANTEE_UID;
835
836 // Generate a key and grant it to a user with GET_INFO permission.
837 let grantor_fn = || {
838 let sl = SecLevel::tee();
839 let alias = format!("ks_ungrant_test_key_1{}", getuid());
840 let access_vector = KeyPermission::GET_INFO.0;
841 let mut grant_keys = generate_ec_key_and_grant_to_users(
842 &sl,
843 Some(alias.to_string()),
844 vec![GRANTEE_UID.try_into().unwrap()],
845 access_vector,
846 )
847 .unwrap();
848
849 let grant_key_nspace = grant_keys.remove(0);
850
851 // Ungrant above granted key.
852 sl.keystore2
853 .ungrant(
854 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
855 GRANTEE_UID.try_into().unwrap(),
856 )
857 .unwrap();
858
859 grant_key_nspace
860 };
861
862 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
863 // `--test-threads=1`), and nothing yet done with binder.
864 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
865
866 // Grantee context, try to load the ungranted key.
867 let grantee_fn = move || {
868 let keystore2 = get_keystore_service();
869 let result = get_granted_key(&keystore2, grant_key_nspace);
870 assert!(result.is_err());
871 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
872 };
873
874 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
875 // `--test-threads=1`), and nothing yet done with binder.
876 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
877 }
878
879 /// Generate a key, grant it to the user and then delete the granted key. Try to ungrant
880 /// a deleted key. Test should fail to ungrant a non-existing key with `KEY_NOT_FOUND` error
881 /// response. Generate a new key with the same alias and try to access the previously granted
882 /// key in grantee context. Test should fail to load the granted key in grantee context as the
883 /// associated key is deleted from grantor context.
884 #[test]
ungrant_deleted_app_key_fails()885 fn ungrant_deleted_app_key_fails() {
886 const APPLICATION_ID: u32 = 10001;
887 const USER_ID: u32 = 99;
888 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
889 static GRANTEE_GID: u32 = GRANTEE_UID;
890
891 let grantor_fn = || {
892 let sl = SecLevel::tee();
893 let alias = format!("{}{}", "ks_grant_delete_ungrant_test_key_1", getuid());
894
895 let key_metadata = key_generations::generate_ec_p256_signing_key(
896 &sl,
897 Domain::SELINUX,
898 key_generations::SELINUX_SHELL_NAMESPACE,
899 Some(alias.to_string()),
900 None,
901 )
902 .unwrap();
903
904 let access_vector = KeyPermission::GET_INFO.0;
905 let grant_key = sl
906 .keystore2
907 .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
908 .unwrap();
909 assert_eq!(grant_key.domain, Domain::GRANT);
910
911 // Delete above granted key.
912 sl.keystore2.deleteKey(&key_metadata.key).unwrap();
913
914 // Try to ungrant above granted key.
915 let result =
916 map_ks_error(sl.keystore2.ungrant(&key_metadata.key, GRANTEE_UID.try_into().unwrap()));
917 assert!(result.is_err());
918 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
919
920 // Generate a new key with the same alias and try to access the earlier granted key
921 // in grantee context.
922 let result = key_generations::generate_ec_p256_signing_key(
923 &sl,
924 Domain::SELINUX,
925 key_generations::SELINUX_SHELL_NAMESPACE,
926 Some(alias),
927 None,
928 );
929 assert!(result.is_ok());
930
931 grant_key.nspace
932 };
933
934 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
935 // `--test-threads=1`), and nothing yet done with binder.
936 let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
937
938 // Make sure grant did not persist, try to access the earlier granted key in grantee context.
939 // Grantee context should fail to load the granted key as its associated key is deleted in
940 // grantor context.
941 let grantee_fn = move || {
942 let keystore2 = get_keystore_service();
943 let result = get_granted_key(&keystore2, grant_key_nspace);
944 assert!(result.is_err());
945 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
946 };
947
948 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
949 // `--test-threads=1`), and nothing yet done with binder.
950 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
951 }
952
953 /// Grant a key to multiple users. Verify that all grantees should succeed in loading the key and
954 /// use it for performing an operation successfully.
955 #[test]
grant_app_key_to_multi_users_success()956 fn grant_app_key_to_multi_users_success() {
957 const APPLICATION_ID: u32 = 10001;
958 const USER_ID_1: u32 = 99;
959 static GRANTEE_1_UID: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID;
960 static GRANTEE_1_GID: u32 = GRANTEE_1_UID;
961
962 const USER_ID_2: u32 = 98;
963 static GRANTEE_2_UID: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID;
964 static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
965
966 // Generate a key and grant it to multiple users with GET_INFO|USE permissions.
967 let grantor_fn = || {
968 let sl = SecLevel::tee();
969 let alias = format!("ks_grant_test_key_2{}", getuid());
970 let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
971
972 generate_ec_key_and_grant_to_users(
973 &sl,
974 Some(alias),
975 vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
976 access_vector,
977 )
978 .unwrap()
979 };
980
981 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
982 // `--test-threads=1`), and nothing yet done with binder.
983 let mut grant_keys = unsafe { run_as::run_as_root(grantor_fn) };
984
985 for (grantee_uid, grantee_gid) in
986 &[(GRANTEE_1_UID, GRANTEE_1_GID), (GRANTEE_2_UID, GRANTEE_2_GID)]
987 {
988 let grant_key_nspace = grant_keys.remove(0);
989 let grantee_fn = move || {
990 assert_eq!(Ok(()), sign_with_granted_key(grant_key_nspace));
991 };
992 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
993 // `--test-threads=1`), and nothing yet done with binder.
994 unsafe { run_as::run_as_app(*grantee_uid, *grantee_gid, grantee_fn) };
995 }
996 }
997
998 /// Grant a key to multiple users with GET_INFO|DELETE permissions. In one of the grantee context
999 /// use the key and delete it. Try to load the granted key in another grantee context. Test should
1000 /// fail to load the granted key with `KEY_NOT_FOUND` error response.
1001 #[test]
grant_app_key_to_multi_users_delete_then_key_not_found()1002 fn grant_app_key_to_multi_users_delete_then_key_not_found() {
1003 const USER_ID_1: u32 = 99;
1004 const APPLICATION_ID: u32 = 10001;
1005 static GRANTEE_1_UID: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID;
1006 static GRANTEE_1_GID: u32 = GRANTEE_1_UID;
1007
1008 const USER_ID_2: u32 = 98;
1009 static GRANTEE_2_UID: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID;
1010 static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
1011
1012 // Generate a key and grant it to multiple users with GET_INFO permission.
1013 let grantor_fn = || {
1014 let sl = SecLevel::tee();
1015 let alias = format!("ks_grant_test_key_2{}", getuid());
1016 let access_vector =
1017 KeyPermission::GET_INFO.0 | KeyPermission::USE.0 | KeyPermission::DELETE.0;
1018
1019 generate_ec_key_and_grant_to_users(
1020 &sl,
1021 Some(alias),
1022 vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
1023 access_vector,
1024 )
1025 .unwrap()
1026 };
1027
1028 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1029 // `--test-threads=1`), and nothing yet done with binder.
1030 let mut grant_keys = unsafe { run_as::run_as_root(grantor_fn) };
1031
1032 // Grantee #1 context
1033 let grant_key1_nspace = grant_keys.remove(0);
1034 let grantee1_fn = move || {
1035 assert_eq!(Ok(()), sign_with_granted_key(grant_key1_nspace));
1036
1037 // Delete the granted key.
1038 get_keystore_service().deleteKey(&granted_key_descriptor(grant_key1_nspace)).unwrap();
1039 };
1040
1041 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1042 // `--test-threads=1`), and nothing yet done with binder.
1043 unsafe { run_as::run_as_app(GRANTEE_1_UID, GRANTEE_1_GID, grantee1_fn) };
1044
1045 // Grantee #2 context
1046 let grant_key2_nspace = grant_keys.remove(0);
1047 let grantee2_fn = move || {
1048 let keystore2 = get_keystore_service();
1049
1050 let result =
1051 map_ks_error(keystore2.getKeyEntry(&granted_key_descriptor(grant_key2_nspace)));
1052 assert!(result.is_err());
1053 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
1054 };
1055
1056 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1057 // `--test-threads=1`), and nothing yet done with binder.
1058 unsafe { run_as::run_as_app(GRANTEE_2_UID, GRANTEE_2_GID, grantee2_fn) };
1059 }
1060