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