• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
16     ErrorCode::ErrorCode, SecurityLevel::SecurityLevel,
17 };
18 use android_system_keystore2::aidl::android::system::keystore2::{
19     Domain::Domain, KeyDescriptor::KeyDescriptor, KeyPermission::KeyPermission,
20     ResponseCode::ResponseCode,
21 };
22 use keystore2_test_utils::{
23     get_keystore_service, key_generations, key_generations::Error, run_as, SecLevel,
24 };
25 use nix::unistd::getuid;
26 use rustutils::users::AID_USER_OFFSET;
27 
28 /// Generate a key and update its public certificate and certificate chain. Test should be able to
29 /// load the key and able to verify whether its certificate and cert-chain are updated successfully.
30 #[test]
keystore2_update_subcomponent_success()31 fn keystore2_update_subcomponent_success() {
32     let alias = "update_subcomponent_success_key";
33 
34     let sl = SecLevel::tee();
35 
36     let key_metadata = key_generations::generate_ec_p256_signing_key(
37         &sl,
38         Domain::SELINUX,
39         key_generations::SELINUX_SHELL_NAMESPACE,
40         Some(alias.to_string()),
41         None,
42     )
43     .unwrap();
44 
45     let other_cert: [u8; 32] = [123; 32];
46     let other_cert_chain: [u8; 32] = [12; 32];
47 
48     sl.keystore2
49         .updateSubcomponent(&key_metadata.key, Some(&other_cert), Some(&other_cert_chain))
50         .expect("updateSubcomponent should have succeeded.");
51 
52     let key_entry_response = sl.keystore2.getKeyEntry(&key_metadata.key).unwrap();
53     assert_eq!(Some(other_cert.to_vec()), key_entry_response.metadata.certificate);
54     assert_eq!(Some(other_cert_chain.to_vec()), key_entry_response.metadata.certificateChain);
55 }
56 
57 /// Try to update non-existing asymmetric key public cert and certificate chain. Test should fail
58 /// to update with error response code `KEY_NOT_FOUND`.
59 #[test]
keystore2_update_subcomponent_fail()60 fn keystore2_update_subcomponent_fail() {
61     let alias = "update_component_failure_key";
62 
63     let keystore2 = get_keystore_service();
64 
65     let other_cert: [u8; 32] = [123; 32];
66     let other_cert_chain: [u8; 32] = [12; 32];
67 
68     let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
69         &KeyDescriptor {
70             domain: Domain::SELINUX,
71             nspace: key_generations::SELINUX_SHELL_NAMESPACE,
72             alias: Some(alias.to_string()),
73             blob: None,
74         },
75         Some(&other_cert),
76         Some(&other_cert_chain),
77     ));
78     assert!(result.is_err());
79     assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
80 }
81 
82 /// Try to update non-existing asymmetric key public cert only. Test should fail
83 /// to update with error response code `KEY_NOT_FOUND`.
84 #[test]
keystore2_update_subcomponent_no_key_entry_cert_fail()85 fn keystore2_update_subcomponent_no_key_entry_cert_fail() {
86     let alias = "update_no_key_entry_cert_only_component_fail_key";
87     let keystore2 = get_keystore_service();
88     let other_cert: [u8; 32] = [123; 32];
89 
90     let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
91         &KeyDescriptor {
92             domain: Domain::APP,
93             nspace: -1,
94             alias: Some(alias.to_string()),
95             blob: None,
96         },
97         Some(&other_cert),
98         None,
99     ));
100     assert!(result.is_err());
101     assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
102 }
103 
104 /// Try to update non existing key with the only given certificate-chain, test should succeed
105 /// in creating a new keystore entry with the given certificate-chain.
106 #[test]
keystore2_update_subcomponent_no_key_entry_cert_chain_success()107 fn keystore2_update_subcomponent_no_key_entry_cert_chain_success() {
108     let alias = "update_no_key_entry_cert_chain_only_component_success";
109     let keystore2 = get_keystore_service();
110     let cert_entries =
111         vec![(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE), (Domain::APP, -1)];
112     let other_cert_chain: [u8; 32] = [12; 32];
113 
114     for (domain, nspace) in cert_entries {
115         keystore2
116             .updateSubcomponent(
117                 &KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None },
118                 None,
119                 Some(&other_cert_chain),
120             )
121             .expect("updateSubcomponent should have succeeded.");
122 
123         let key_entry_response = keystore2
124             .getKeyEntry(&KeyDescriptor {
125                 domain,
126                 nspace,
127                 alias: Some(alias.to_string()),
128                 blob: None,
129             })
130             .unwrap();
131         assert_eq!(Some(other_cert_chain.to_vec()), key_entry_response.metadata.certificateChain);
132         assert!(key_entry_response.metadata.certificate.is_none(), "Unexpected certificate entry");
133         assert!(key_entry_response.metadata.authorizations.is_empty(), "Unexpected authorizations");
134         assert_eq!(key_entry_response.metadata.keySecurityLevel, SecurityLevel::SOFTWARE);
135 
136         keystore2
137             .deleteKey(&KeyDescriptor {
138                 domain,
139                 nspace,
140                 alias: Some(alias.to_string()),
141                 blob: None,
142             })
143             .unwrap();
144     }
145 }
146 
147 /// Generate a key and grant it to two users. For one user grant it with only `GET_INFO` access
148 /// permission and for another user grant it with GET_INFO and UPDATE access permissions. In a
149 /// grantee context where key is granted with only GET_INFO access permission, try to update
150 /// key's public certificate and certificate chain. Test should fail to update with error response
151 /// code `PERMISSION_DENIED` because grantee does not possess UPDATE access permission for the
152 /// specified key. In a grantee context where key is granted with UPDATE and GET_INFO access
153 /// permissions, test should be able to update public certificate and cert-chain successfully.
154 #[test]
keystore2_update_subcomponent_fails_permission_denied()155 fn keystore2_update_subcomponent_fails_permission_denied() {
156     const USER_ID_1: u32 = 99;
157     const APPLICATION_ID: u32 = 10001;
158     static GRANTEE_1_UID: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID;
159     static GRANTEE_1_GID: u32 = GRANTEE_1_UID;
160 
161     const USER_ID_2: u32 = 98;
162     static GRANTEE_2_UID: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID;
163     static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
164 
165     // Generate a key and grant it to multiple users with different access permissions.
166     let grantor_fn = || {
167         let sl = SecLevel::tee();
168         let alias = format!("ks_update_subcompo_test_1_{}", getuid());
169         let mut granted_keys = Vec::new();
170 
171         let key_metadata =
172             key_generations::generate_ec_p256_signing_key(&sl, Domain::APP, -1, Some(alias), None)
173                 .unwrap();
174 
175         // Grant a key without update permission.
176         let access_vector = KeyPermission::GET_INFO.0;
177         let granted_key = sl
178             .keystore2
179             .grant(&key_metadata.key, GRANTEE_1_UID.try_into().unwrap(), access_vector)
180             .unwrap();
181         assert_eq!(granted_key.domain, Domain::GRANT);
182         granted_keys.push(granted_key.nspace);
183 
184         // Grant a key with update permission.
185         let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::UPDATE.0;
186         let granted_key = sl
187             .keystore2
188             .grant(&key_metadata.key, GRANTEE_2_UID.try_into().unwrap(), access_vector)
189             .unwrap();
190         assert_eq!(granted_key.domain, Domain::GRANT);
191         granted_keys.push(granted_key.nspace);
192 
193         granted_keys
194     };
195 
196     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
197     // `--test-threads=1`), and nothing yet done with binder.
198     let mut granted_keys = unsafe { run_as::run_as_root(grantor_fn) };
199 
200     // Grantee context, try to update the key public certs, permission denied error is expected.
201     let granted_key1_nspace = granted_keys.remove(0);
202     let grantee1_fn = move || {
203         let keystore2 = get_keystore_service();
204 
205         let other_cert: [u8; 32] = [123; 32];
206         let other_cert_chain: [u8; 32] = [12; 32];
207 
208         let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
209             &KeyDescriptor {
210                 domain: Domain::GRANT,
211                 nspace: granted_key1_nspace,
212                 alias: None,
213                 blob: None,
214             },
215             Some(&other_cert),
216             Some(&other_cert_chain),
217         ));
218         assert!(result.is_err());
219         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
220     };
221 
222     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
223     // `--test-threads=1`), and nothing yet done with binder.
224     unsafe { run_as::run_as_app(GRANTEE_1_UID, GRANTEE_1_GID, grantee1_fn) };
225 
226     // Grantee context, update granted key public certs. Update should happen successfully.
227     let granted_key2_nspace = granted_keys.remove(0);
228     let grantee2_fn = move || {
229         let keystore2 = get_keystore_service();
230 
231         let other_cert: [u8; 32] = [124; 32];
232         let other_cert_chain: [u8; 32] = [13; 32];
233 
234         keystore2
235             .updateSubcomponent(
236                 &KeyDescriptor {
237                     domain: Domain::GRANT,
238                     nspace: granted_key2_nspace,
239                     alias: None,
240                     blob: None,
241                 },
242                 Some(&other_cert),
243                 Some(&other_cert_chain),
244             )
245             .expect("updateSubcomponent should have succeeded.");
246 
247         let key_entry_response = keystore2
248             .getKeyEntry(&KeyDescriptor {
249                 domain: Domain::GRANT,
250                 nspace: granted_key2_nspace,
251                 alias: None,
252                 blob: None,
253             })
254             .unwrap();
255         assert_eq!(Some(other_cert.to_vec()), key_entry_response.metadata.certificate);
256         assert_eq!(Some(other_cert_chain.to_vec()), key_entry_response.metadata.certificateChain);
257     };
258 
259     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
260     // `--test-threads=1`), and nothing yet done with binder.
261     unsafe { run_as::run_as_app(GRANTEE_2_UID, GRANTEE_2_GID, grantee2_fn) };
262 }
263 
264 #[test]
keystore2_get_security_level_success()265 fn keystore2_get_security_level_success() {
266     let keystore2 = get_keystore_service();
267     assert!(
268         keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).is_ok(),
269         "getSecurityLevel with SecurityLevel::TRUSTED_ENVIRONMENT should have succeeded."
270     );
271 }
272 
273 #[test]
keystore2_get_security_level_failure()274 fn keystore2_get_security_level_failure() {
275     let keystore2 = get_keystore_service();
276     let result = key_generations::map_ks_error(keystore2.getSecurityLevel(SecurityLevel::SOFTWARE));
277 
278     assert!(result.is_err());
279     assert_eq!(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE), result.unwrap_err());
280 }
281