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::{delete_all_entries, delete_app_key, verify_aliases};
16 use android_system_keystore2::aidl::android::system::keystore2::{
17 Domain::Domain, IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor,
18 KeyPermission::KeyPermission, ResponseCode::ResponseCode,
19 };
20 use keystore2_test_utils::{
21 get_keystore_service, key_generations, key_generations::Error, run_as, SecLevel,
22 };
23 use nix::unistd::getuid;
24 use rustutils::users::AID_USER_OFFSET;
25 use std::collections::HashSet;
26 use std::fmt::Write;
27
28 /// Try to find a key with given key parameters using `listEntries` API.
key_alias_exists( keystore2: &binder::Strong<dyn IKeystoreService>, domain: Domain, nspace: i64, alias: String, ) -> bool29 fn key_alias_exists(
30 keystore2: &binder::Strong<dyn IKeystoreService>,
31 domain: Domain,
32 nspace: i64,
33 alias: String,
34 ) -> bool {
35 let key_descriptors = keystore2.listEntries(domain, nspace).unwrap();
36 let alias_count = key_descriptors
37 .into_iter()
38 .map(|key| key.alias.unwrap())
39 .filter(|key_alias| *key_alias == alias)
40 .count();
41
42 alias_count != 0
43 }
44
45 /// List key entries with domain as SELINUX and APP.
46 /// 1. Generate a key with domain as SELINUX and find this key entry in list of keys retrieved from
47 /// `listEntries` with domain SELINUX. Test should be able find this key entry successfully.
48 /// 2. Grant above generated Key to a user.
49 /// 3. In a user context, generate a new key with domain as APP. Try to list the key entries with
50 /// domain APP. Test should find only one key entry that should be the key generated in user
51 /// context. GRANT keys shouldn't be part of this list.
52 #[test]
keystore2_list_entries_success()53 fn keystore2_list_entries_success() {
54 const USER_ID: u32 = 91;
55 const APPLICATION_ID: u32 = 10006;
56 static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
57 static GRANTEE_GID: u32 = GRANTEE_UID;
58
59 let gen_key_fn = || {
60 let sl = SecLevel::tee();
61
62 let alias = format!("list_entries_grant_key1_{}", getuid());
63
64 // Make sure there is no key exist with this `alias` in `SELINUX` domain and
65 // `SELINUX_SHELL_NAMESPACE` namespace.
66 if key_alias_exists(
67 &sl.keystore2,
68 Domain::SELINUX,
69 key_generations::SELINUX_SHELL_NAMESPACE,
70 alias.to_string(),
71 ) {
72 sl.keystore2
73 .deleteKey(&KeyDescriptor {
74 domain: Domain::SELINUX,
75 nspace: key_generations::SELINUX_SHELL_NAMESPACE,
76 alias: Some(alias.to_string()),
77 blob: None,
78 })
79 .unwrap();
80 }
81
82 // Generate a key with above defined `alias`.
83 let key_metadata = key_generations::generate_ec_p256_signing_key(
84 &sl,
85 Domain::SELINUX,
86 key_generations::SELINUX_SHELL_NAMESPACE,
87 Some(alias.to_string()),
88 None,
89 )
90 .unwrap();
91
92 // Verify that above generated key entry is listed with domain SELINUX and
93 // namespace SELINUX_SHELL_NAMESPACE
94 assert!(key_alias_exists(
95 &sl.keystore2,
96 Domain::SELINUX,
97 key_generations::SELINUX_SHELL_NAMESPACE,
98 alias,
99 ));
100
101 // Grant a key with GET_INFO permission.
102 let access_vector = KeyPermission::GET_INFO.0;
103 sl.keystore2
104 .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
105 .unwrap();
106 };
107
108 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
109 // `--test-threads=1`), and nothing yet done with binder.
110 unsafe { run_as::run_as_root(gen_key_fn) };
111
112 // In user context validate list of key entries associated with it.
113 let list_keys_fn = move || {
114 let sl = SecLevel::tee();
115 let alias = format!("list_entries_success_key{}", getuid());
116
117 let key_metadata = key_generations::generate_ec_p256_signing_key(
118 &sl,
119 Domain::APP,
120 -1,
121 Some(alias.to_string()),
122 None,
123 )
124 .unwrap();
125
126 // Make sure there is only one existing key entry and that should be the same key
127 // generated in this user context. Granted key shouldn't be included in this list.
128 let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
129 assert_eq!(1, key_descriptors.len());
130
131 let key = key_descriptors.first().unwrap();
132 assert_eq!(key.alias, Some(alias));
133 assert_eq!(key.nspace, GRANTEE_UID.try_into().unwrap());
134 assert_eq!(key.domain, Domain::APP);
135
136 sl.keystore2.deleteKey(&key_metadata.key).unwrap();
137
138 let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
139 assert_eq!(0, key_descriptors.len());
140 };
141
142 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
143 // `--test-threads=1`), and nothing yet done with binder.
144 unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, list_keys_fn) };
145 }
146
147 /// Try to list the key entries with domain SELINUX from user context where user doesn't possesses
148 /// `GET_INFO` permission for specified namespace. Test should fail to list key entries with error
149 /// response code `PERMISSION_DENIED`.
150 #[test]
keystore2_list_entries_fails_perm_denied()151 fn keystore2_list_entries_fails_perm_denied() {
152 let auid = 91 * AID_USER_OFFSET + 10001;
153 let agid = 91 * AID_USER_OFFSET + 10001;
154 let list_keys_fn = move || {
155 let keystore2 = get_keystore_service();
156
157 let result = key_generations::map_ks_error(
158 keystore2.listEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
159 );
160 assert!(result.is_err());
161 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
162 };
163
164 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
165 // `--test-threads=1`), and nothing yet done with binder.
166 unsafe { run_as::run_as_app(auid, agid, list_keys_fn) };
167 }
168
169 /// Try to list key entries with domain BLOB. Test should fail with error repose code
170 /// `INVALID_ARGUMENT`.
171 #[test]
keystore2_list_entries_fails_invalid_arg()172 fn keystore2_list_entries_fails_invalid_arg() {
173 let keystore2 = get_keystore_service();
174
175 let result = key_generations::map_ks_error(
176 keystore2.listEntries(Domain::BLOB, key_generations::SELINUX_SHELL_NAMESPACE),
177 );
178 assert!(result.is_err());
179 assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
180 }
181
182 /// Import large number of Keystore entries with long aliases and try to list aliases
183 /// of all the entries in the keystore.
184 #[test]
keystore2_list_entries_with_long_aliases_success()185 fn keystore2_list_entries_with_long_aliases_success() {
186 const USER_ID: u32 = 92;
187 const APPLICATION_ID: u32 = 10002;
188 static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
189 static CLIENT_GID: u32 = CLIENT_UID;
190
191 let import_keys_fn = || {
192 let sl = SecLevel::tee();
193
194 // Make sure there are no keystore entries exist before adding new entries.
195 let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
196 if !key_descriptors.is_empty() {
197 key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
198 delete_app_key(&sl.keystore2, &alias).unwrap();
199 });
200 }
201
202 let mut imported_key_aliases = HashSet::new();
203
204 // Import 100 keys with aliases of length 6000.
205 for count in 1..101 {
206 let mut alias = String::new();
207 write!(alias, "{}_{}", "X".repeat(6000), count).unwrap();
208 imported_key_aliases.insert(alias.clone());
209
210 let result = key_generations::import_aes_key(&sl, Domain::APP, -1, Some(alias));
211 assert!(result.is_ok());
212 }
213
214 // b/222287335 Limiting Keystore `listEntries` API to return subset of the Keystore
215 // entries to avoid running out of binder buffer space.
216 // To verify that all the imported key aliases are present in Keystore,
217 // - get the list of entries from Keystore
218 // - check whether the retrieved key entries list is a subset of imported key aliases
219 // - delete this subset of keystore entries from Keystore as well as from imported
220 // list of key aliases
221 // - continue above steps till it cleanup all the imported keystore entries.
222 while !imported_key_aliases.is_empty() {
223 let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
224
225 // Check retrieved key entries list is a subset of imported keys list.
226 assert!(key_descriptors
227 .iter()
228 .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
229
230 // Delete the listed key entries from Keystore as well as from imported keys list.
231 key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
232 delete_app_key(&sl.keystore2, &alias).unwrap();
233 assert!(imported_key_aliases.remove(&alias));
234 });
235 }
236
237 assert!(imported_key_aliases.is_empty());
238 };
239
240 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
241 // `--test-threads=1`), and nothing yet done with binder.
242 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, import_keys_fn) };
243 }
244
245 /// Import large number of Keystore entries with long aliases such that the
246 /// aliases list would exceed the binder transaction size limit.
247 /// Try to list aliases of all the entries in the keystore using `listEntriesBatched` API.
248 #[test]
keystore2_list_entries_batched_with_long_aliases_success()249 fn keystore2_list_entries_batched_with_long_aliases_success() {
250 const USER_ID: u32 = 92;
251 const APPLICATION_ID: u32 = 10002;
252 static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
253 static CLIENT_GID: u32 = CLIENT_UID;
254
255 let import_keys_fn = || {
256 let sl = SecLevel::tee();
257
258 // Make sure there are no keystore entries exist before adding new entries.
259 delete_all_entries(&sl.keystore2);
260
261 // Import 100 keys with aliases of length 6000.
262 let mut imported_key_aliases =
263 key_generations::import_aes_keys(&sl, "X".repeat(6000), 1..101).unwrap();
264 assert_eq!(
265 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
266 100,
267 "Error while importing keys"
268 );
269
270 let mut start_past_alias = None;
271 let mut alias;
272 while !imported_key_aliases.is_empty() {
273 let key_descriptors =
274 sl.keystore2.listEntriesBatched(Domain::APP, -1, start_past_alias).unwrap();
275
276 // Check retrieved key entries list is a subset of imported keys list.
277 assert!(key_descriptors
278 .iter()
279 .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
280
281 alias = key_descriptors.last().unwrap().alias.clone().unwrap();
282 start_past_alias = Some(alias.as_ref());
283 // Delete the listed key entries from imported keys list.
284 key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
285 assert!(imported_key_aliases.remove(&alias));
286 });
287 }
288
289 assert!(imported_key_aliases.is_empty());
290 delete_all_entries(&sl.keystore2);
291 assert_eq!(
292 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
293 0,
294 "Error while doing cleanup"
295 );
296 };
297
298 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
299 // `--test-threads=1`), and nothing yet done with binder.
300 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, import_keys_fn) };
301 }
302
303 /// Import keys from multiple processes with same user context and try to list the keystore entries
304 /// using `listEntriesBatched` API.
305 /// - Create two processes sharing user-id.
306 /// - From process-1, import 3 keys and try to list the keys using `listEntriesBatched`
307 /// without `startingPastAlias`, it should list all the 3 entries.
308 /// - From process-2, import another 5 keys and try to list the keys using `listEntriesBatched`
309 /// with the alias of the last key listed in process-1 as `startingPastAlias`. It should list
310 /// all the entries whose alias is greater than the provided `startingPastAlias`.
311 /// - From process-2 try to list all entries accessible to it by using `listEntriesBatched` with
312 /// `startingPastAlias` as None. It should list all the keys imported in process-1 and process-2.
313 #[test]
keystore2_list_entries_batched_with_multi_procs_success()314 fn keystore2_list_entries_batched_with_multi_procs_success() {
315 const USER_ID: u32 = 92;
316 const APPLICATION_ID: u32 = 10002;
317 static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
318 static CLIENT_GID: u32 = CLIENT_UID;
319 static ALIAS_PREFIX: &str = "key_test_batch_list";
320
321 let import_keys_fn = || {
322 let sl = SecLevel::tee();
323
324 // Make sure there are no keystore entries exist before adding new entries.
325 delete_all_entries(&sl.keystore2);
326
327 // Import 3 keys with below aliases -
328 // [key_test_batch_list_1, key_test_batch_list_2, key_test_batch_list_3]
329 let imported_key_aliases =
330 key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..4).unwrap();
331 assert_eq!(
332 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
333 3,
334 "Error while importing keys"
335 );
336
337 // List all entries in keystore for this user-id.
338 let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
339 assert_eq!(key_descriptors.len(), 3);
340
341 // Makes sure all listed aliases are matching with imported keys aliases.
342 assert!(key_descriptors
343 .iter()
344 .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
345 };
346
347 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
348 // `--test-threads=1`), and nothing yet done with binder.
349 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, import_keys_fn) };
350
351 let import_more_fn = || {
352 let sl = SecLevel::tee();
353
354 // Import another 5 keys with below aliases -
355 // [ key_test_batch_list_4, key_test_batch_list_5, key_test_batch_list_6,
356 // key_test_batch_list_7, key_test_batch_list_8 ]
357 let mut imported_key_aliases =
358 key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 4..9).unwrap();
359
360 // Above context already 3 keys are imported, in this context 5 keys are imported,
361 // total 8 keystore entries are expected to be present in Keystore for this user-id.
362 assert_eq!(
363 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
364 8,
365 "Error while importing keys"
366 );
367
368 // List keystore entries with `start_past_alias` as "key_test_batch_list_3".
369 // `listEntriesBatched` should list all the keystore entries with
370 // alias > "key_test_batch_list_3".
371 let key_descriptors = sl
372 .keystore2
373 .listEntriesBatched(Domain::APP, -1, Some("key_test_batch_list_3"))
374 .unwrap();
375 assert_eq!(key_descriptors.len(), 5);
376
377 // Make sure above listed aliases are matching with imported keys aliases.
378 assert!(key_descriptors
379 .iter()
380 .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
381
382 // List all keystore entries with `start_past_alias` as `None`.
383 // `listEntriesBatched` should list all the keystore entries.
384 let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
385 assert_eq!(key_descriptors.len(), 8);
386
387 // Include previously imported keys aliases as well
388 imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_1");
389 imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_2");
390 imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_3");
391
392 // Make sure all the above listed aliases are matching with imported keys aliases.
393 assert!(key_descriptors
394 .iter()
395 .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
396
397 delete_all_entries(&sl.keystore2);
398 assert_eq!(
399 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
400 0,
401 "Error while doing cleanup"
402 );
403 };
404
405 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
406 // `--test-threads=1`), and nothing yet done with binder.
407 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, import_more_fn) };
408 }
409
410 #[test]
keystore2_list_entries_batched_with_empty_keystore_success()411 fn keystore2_list_entries_batched_with_empty_keystore_success() {
412 const USER_ID: u32 = 92;
413 const APPLICATION_ID: u32 = 10002;
414 static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
415 static CLIENT_GID: u32 = CLIENT_UID;
416
417 let list_keys_fn = || {
418 let keystore2 = get_keystore_service();
419
420 // Make sure there are no keystore entries exist before adding new entries.
421 delete_all_entries(&keystore2);
422
423 // List all entries in keystore for this user-id, pass startingPastAlias = None
424 let key_descriptors = keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
425 assert_eq!(key_descriptors.len(), 0);
426
427 // List all entries in keystore for this user-id, pass startingPastAlias = <random value>
428 let key_descriptors =
429 keystore2.listEntriesBatched(Domain::APP, -1, Some("startingPastAlias")).unwrap();
430 assert_eq!(key_descriptors.len(), 0);
431 };
432
433 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
434 // `--test-threads=1`), and nothing yet done with binder.
435 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, list_keys_fn) };
436 }
437
438 /// Import a key with SELINUX as domain, list aliases using `listEntriesBatched`.
439 /// Test should successfully list the imported key.
440 #[test]
keystore2_list_entries_batched_with_selinux_domain_success()441 fn keystore2_list_entries_batched_with_selinux_domain_success() {
442 let sl = SecLevel::tee();
443
444 let alias = "test_selinux_key_list_alias_batched";
445 let _result = sl.keystore2.deleteKey(&KeyDescriptor {
446 domain: Domain::SELINUX,
447 nspace: key_generations::SELINUX_SHELL_NAMESPACE,
448 alias: Some(alias.to_string()),
449 blob: None,
450 });
451
452 let initial_count = sl
453 .keystore2
454 .getNumberOfEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE)
455 .unwrap();
456
457 key_generations::import_aes_key(
458 &sl,
459 Domain::SELINUX,
460 key_generations::SELINUX_SHELL_NAMESPACE,
461 Some(alias.to_string()),
462 )
463 .unwrap();
464
465 assert_eq!(
466 sl.keystore2
467 .getNumberOfEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE)
468 .unwrap(),
469 initial_count + 1,
470 "Error while getting number of keystore entries accessible."
471 );
472
473 let key_descriptors = sl
474 .keystore2
475 .listEntriesBatched(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE, None)
476 .unwrap();
477 assert_eq!(key_descriptors.len(), (initial_count + 1) as usize);
478
479 let count =
480 key_descriptors.into_iter().map(|key| key.alias.unwrap()).filter(|a| a == alias).count();
481 assert_eq!(count, 1);
482
483 sl.keystore2
484 .deleteKey(&KeyDescriptor {
485 domain: Domain::SELINUX,
486 nspace: key_generations::SELINUX_SHELL_NAMESPACE,
487 alias: Some(alias.to_string()),
488 blob: None,
489 })
490 .unwrap();
491 }
492
493 #[test]
keystore2_list_entries_batched_validate_count_and_order_success()494 fn keystore2_list_entries_batched_validate_count_and_order_success() {
495 const USER_ID: u32 = 92;
496 const APPLICATION_ID: u32 = 10002;
497 static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
498 static CLIENT_GID: u32 = CLIENT_UID;
499 static ALIAS_PREFIX: &str = "key_test_batch_list";
500
501 let list_keys_fn = || {
502 let sl = SecLevel::tee();
503
504 // Make sure there are no keystore entries exist before adding new entries.
505 delete_all_entries(&sl.keystore2);
506
507 // Import keys with below mentioned aliases -
508 // [
509 // key_test_batch_list_1,
510 // key_test_batch_list_2,
511 // key_test_batch_list_3,
512 // key_test_batch_list_4,
513 // key_test_batch_list_5,
514 // key_test_batch_list_10,
515 // key_test_batch_list_11,
516 // key_test_batch_list_12,
517 // key_test_batch_list_21,
518 // key_test_batch_list_22,
519 // ]
520 let _imported_key_aliases =
521 key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..6).unwrap();
522 assert_eq!(
523 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
524 5,
525 "Error while importing keys"
526 );
527 let _imported_key_aliases =
528 key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 10..13).unwrap();
529 assert_eq!(
530 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
531 8,
532 "Error while importing keys"
533 );
534 let _imported_key_aliases =
535 key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 21..23).unwrap();
536 assert_eq!(
537 sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
538 10,
539 "Error while importing keys"
540 );
541
542 // List the aliases using given `startingPastAlias` and verify the listed
543 // aliases with the expected list of aliases.
544 verify_aliases(&sl.keystore2, Some(format!("{}{}", ALIAS_PREFIX, "_5").as_str()), vec![]);
545
546 verify_aliases(
547 &sl.keystore2,
548 Some(format!("{}{}", ALIAS_PREFIX, "_4").as_str()),
549 vec![ALIAS_PREFIX.to_owned() + "_5"],
550 );
551
552 verify_aliases(
553 &sl.keystore2,
554 Some(format!("{}{}", ALIAS_PREFIX, "_3").as_str()),
555 vec![ALIAS_PREFIX.to_owned() + "_4", ALIAS_PREFIX.to_owned() + "_5"],
556 );
557
558 verify_aliases(
559 &sl.keystore2,
560 Some(format!("{}{}", ALIAS_PREFIX, "_2").as_str()),
561 vec![
562 ALIAS_PREFIX.to_owned() + "_21",
563 ALIAS_PREFIX.to_owned() + "_22",
564 ALIAS_PREFIX.to_owned() + "_3",
565 ALIAS_PREFIX.to_owned() + "_4",
566 ALIAS_PREFIX.to_owned() + "_5",
567 ],
568 );
569
570 verify_aliases(
571 &sl.keystore2,
572 Some(format!("{}{}", ALIAS_PREFIX, "_1").as_str()),
573 vec![
574 ALIAS_PREFIX.to_owned() + "_10",
575 ALIAS_PREFIX.to_owned() + "_11",
576 ALIAS_PREFIX.to_owned() + "_12",
577 ALIAS_PREFIX.to_owned() + "_2",
578 ALIAS_PREFIX.to_owned() + "_21",
579 ALIAS_PREFIX.to_owned() + "_22",
580 ALIAS_PREFIX.to_owned() + "_3",
581 ALIAS_PREFIX.to_owned() + "_4",
582 ALIAS_PREFIX.to_owned() + "_5",
583 ],
584 );
585
586 verify_aliases(
587 &sl.keystore2,
588 Some(ALIAS_PREFIX),
589 vec![
590 ALIAS_PREFIX.to_owned() + "_1",
591 ALIAS_PREFIX.to_owned() + "_10",
592 ALIAS_PREFIX.to_owned() + "_11",
593 ALIAS_PREFIX.to_owned() + "_12",
594 ALIAS_PREFIX.to_owned() + "_2",
595 ALIAS_PREFIX.to_owned() + "_21",
596 ALIAS_PREFIX.to_owned() + "_22",
597 ALIAS_PREFIX.to_owned() + "_3",
598 ALIAS_PREFIX.to_owned() + "_4",
599 ALIAS_PREFIX.to_owned() + "_5",
600 ],
601 );
602
603 verify_aliases(
604 &sl.keystore2,
605 None,
606 vec![
607 ALIAS_PREFIX.to_owned() + "_1",
608 ALIAS_PREFIX.to_owned() + "_10",
609 ALIAS_PREFIX.to_owned() + "_11",
610 ALIAS_PREFIX.to_owned() + "_12",
611 ALIAS_PREFIX.to_owned() + "_2",
612 ALIAS_PREFIX.to_owned() + "_21",
613 ALIAS_PREFIX.to_owned() + "_22",
614 ALIAS_PREFIX.to_owned() + "_3",
615 ALIAS_PREFIX.to_owned() + "_4",
616 ALIAS_PREFIX.to_owned() + "_5",
617 ],
618 );
619 };
620
621 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
622 // `--test-threads=1`), and nothing yet done with binder.
623 unsafe { run_as::run_as_app(CLIENT_UID, CLIENT_GID, list_keys_fn) };
624 }
625
626 /// Try to list the key entries with domain SELINUX from user context where user doesn't possesses
627 /// `GET_INFO` permission for specified namespace. Test should fail to list key entries with error
628 /// response code `PERMISSION_DENIED`.
629 #[test]
keystore2_list_entries_batched_fails_perm_denied()630 fn keystore2_list_entries_batched_fails_perm_denied() {
631 let auid = 91 * AID_USER_OFFSET + 10001;
632 let agid = 91 * AID_USER_OFFSET + 10001;
633 let list_keys_fn = move || {
634 let keystore2 = get_keystore_service();
635
636 let result = key_generations::map_ks_error(keystore2.listEntriesBatched(
637 Domain::SELINUX,
638 key_generations::SELINUX_SHELL_NAMESPACE,
639 None,
640 ));
641 assert!(result.is_err());
642 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
643 };
644
645 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
646 // `--test-threads=1`), and nothing yet done with binder.
647 unsafe { run_as::run_as_app(auid, agid, list_keys_fn) };
648 }
649
650 /// Try to list key entries with domain BLOB. Test should fail with error response code
651 /// `INVALID_ARGUMENT`.
652 #[test]
keystore2_list_entries_batched_fails_invalid_arg()653 fn keystore2_list_entries_batched_fails_invalid_arg() {
654 let keystore2 = get_keystore_service();
655
656 let result = key_generations::map_ks_error(keystore2.listEntriesBatched(
657 Domain::BLOB,
658 key_generations::SELINUX_SHELL_NAMESPACE,
659 None,
660 ));
661 assert!(result.is_err());
662 assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
663 }
664
665 /// Try to get the number of key entries with domain SELINUX from user context where user doesn't
666 /// possesses `GET_INFO` permission for specified namespace. Test should fail to list key entries
667 /// with error response code `PERMISSION_DENIED`.
668 #[test]
keystore2_get_number_of_entries_fails_perm_denied()669 fn keystore2_get_number_of_entries_fails_perm_denied() {
670 let auid = 91 * AID_USER_OFFSET + 10001;
671 let agid = 91 * AID_USER_OFFSET + 10001;
672 let get_num_fn = move || {
673 let keystore2 = get_keystore_service();
674
675 let result = key_generations::map_ks_error(
676 keystore2.getNumberOfEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
677 );
678 assert!(result.is_err());
679 assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
680 };
681
682 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
683 // `--test-threads=1`), and nothing yet done with binder.
684 unsafe { run_as::run_as_app(auid, agid, get_num_fn) };
685 }
686
687 /// Try to get number of key entries with domain BLOB. Test should fail with error response code
688 /// `INVALID_ARGUMENT`.
689 #[test]
keystore2_get_number_of_entries_fails_invalid_arg()690 fn keystore2_get_number_of_entries_fails_invalid_arg() {
691 let keystore2 = get_keystore_service();
692
693 let result = key_generations::map_ks_error(
694 keystore2.getNumberOfEntries(Domain::BLOB, key_generations::SELINUX_SHELL_NAMESPACE),
695 );
696 assert!(result.is_err());
697 assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
698 }
699