blob: fe641506faf56ecf6767c09344cc9872fa6d1131 [file] [log] [blame]
Tri Voe8f04442022-12-21 08:53:56 -08001// 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//! Helper wrapper around RKPD interface.
16
Seth Moore484010a2023-01-31 11:22:26 -080017use crate::error::{map_binder_status_code, Error, ResponseCode};
Tri Voe8f04442022-12-21 08:53:56 -080018use android_security_rkp_aidl::aidl::android::security::rkp::{
Seth Moore484010a2023-01-31 11:22:26 -080019 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
20 IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
Tri Voe8f04442022-12-21 08:53:56 -080021 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
Seth Moorea55428e2023-01-10 13:07:31 -080022 IRemoteProvisioning::IRemoteProvisioning,
23 IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
24 IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
25 RemotelyProvisionedKey::RemotelyProvisionedKey,
Tri Voe8f04442022-12-21 08:53:56 -080026};
27use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
28use anyhow::{Context, Result};
Alice Wange66c3312023-11-07 12:41:42 +000029use message_macro::source_location_msg;
Tri Voe8f04442022-12-21 08:53:56 -080030use std::sync::Mutex;
Tri Vo437d0142023-01-18 16:43:49 -080031use std::time::Duration;
32use tokio::sync::oneshot;
33use tokio::time::timeout;
34
35// Normally, we block indefinitely when making calls outside of keystore and rely on watchdog to
36// report deadlocks. However, RKPD is mainline updatable. Also, calls to RKPD may wait on network
37// for certificates. So, we err on the side of caution and timeout instead.
38static RKPD_TIMEOUT: Duration = Duration::from_secs(10);
39
40fn tokio_rt() -> tokio::runtime::Runtime {
41 tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
42}
Tri Voe8f04442022-12-21 08:53:56 -080043
Seth Moorea882c962023-01-09 16:55:10 -080044/// Thread-safe channel for sending a value once and only once. If a value has
45/// already been send, subsequent calls to send will noop.
46struct SafeSender<T> {
47 inner: Mutex<Option<oneshot::Sender<T>>>,
48}
49
50impl<T> SafeSender<T> {
51 fn new(sender: oneshot::Sender<T>) -> Self {
52 Self { inner: Mutex::new(Some(sender)) }
53 }
54
55 fn send(&self, value: T) {
56 if let Some(inner) = self.inner.lock().unwrap().take() {
Tri Vo0e5fe2c2023-02-15 17:02:06 -080057 // It's possible for the corresponding receiver to time out and be dropped. In this
58 // case send() will fail. This error is not actionable though, so only log the error.
59 if inner.send(value).is_err() {
60 log::error!("SafeSender::send() failed");
61 }
Seth Moorea882c962023-01-09 16:55:10 -080062 }
63 }
64}
Tri Voe8f04442022-12-21 08:53:56 -080065
66struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080067 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080068}
69
70impl GetRegistrationCallback {
71 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080072 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -080073 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -080074 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080075 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -080076 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -080077 }
78}
79
80impl Interface for GetRegistrationCallback {}
81
82impl IGetRegistrationCallback for GetRegistrationCallback {
83 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -080084 self.registration_tx.send(Ok(registration.clone()));
85 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080086 }
87 fn onCancel(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -080088 log::warn!("IGetRegistrationCallback cancelled");
89 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -080090 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +000091 .context(source_location_msg!("GetRegistrationCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -080092 );
93 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080094 }
Seth Moore484010a2023-01-31 11:22:26 -080095 fn onError(&self, description: &str) -> binder::Result<()> {
Seth Moore484010a2023-01-31 11:22:26 -080096 log::error!("IGetRegistrationCallback failed: '{description}'");
Alice Wange66c3312023-11-07 12:41:42 +000097 self.registration_tx
98 .send(Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)).context(
99 source_location_msg!("GetRegistrationCallback failed: {:?}", description),
100 ));
Seth Moore613a1fd2023-01-11 10:42:26 -0800101 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800102 }
103}
104
105/// Make a new connection to a IRegistration service.
Alice Wangbf6a6932023-11-07 11:47:12 +0000106async fn get_rkpd_registration(rpc_name: &str) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800107 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
108 map_binder_status_code(binder::get_interface("remote_provisioning"))
Alice Wange66c3312023-11-07 12:41:42 +0000109 .context(source_location_msg!("Trying to connect to IRemoteProvisioning service."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800110
Tri Voe8f04442022-12-21 08:53:56 -0800111 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800112 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800113
114 remote_provisioning
Alice Wangbf6a6932023-11-07 11:47:12 +0000115 .getRegistration(rpc_name, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000116 .context(source_location_msg!("Trying to get registration."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800117
Tri Vo437d0142023-01-18 16:43:49 -0800118 match timeout(RKPD_TIMEOUT, rx).await {
Alice Wange66c3312023-11-07 12:41:42 +0000119 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
120 .context(source_location_msg!("Waiting for RKPD: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800121 Ok(v) => v.unwrap(),
122 }
Tri Voe8f04442022-12-21 08:53:56 -0800123}
124
Tri Voe8f04442022-12-21 08:53:56 -0800125struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800126 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800127}
128
129impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800130 pub fn new_native_binder(
131 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800132 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800133 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800134 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800135 }
136}
137
138impl Interface for GetKeyCallback {}
139
140impl IGetKeyCallback for GetKeyCallback {
141 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800142 self.key_tx.send(Ok(RemotelyProvisionedKey {
143 keyBlob: key.keyBlob.clone(),
144 encodedCertChain: key.encodedCertChain.clone(),
145 }));
146 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800147 }
148 fn onCancel(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800149 log::warn!("IGetKeyCallback cancelled");
150 self.key_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800151 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000152 .context(source_location_msg!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800153 );
154 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800155 }
Seth Moore484010a2023-01-31 11:22:26 -0800156 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Seth Moore484010a2023-01-31 11:22:26 -0800157 log::error!("IGetKeyCallback failed: {description}");
158 let rc = match error {
159 GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
160 GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
161 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
162 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
163 }
164 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
165 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
166 }
167 _ => {
168 log::error!("Unexpected error from rkpd: {error:?}");
169 ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
170 }
171 };
Alice Wange66c3312023-11-07 12:41:42 +0000172 self.key_tx.send(Err(Error::Rc(rc)).context(source_location_msg!(
Seth Moore484010a2023-01-31 11:22:26 -0800173 "GetKeyCallback failed: {:?} {:?}",
174 error,
175 description
176 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800177 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800178 }
179}
180
Tri Vo437d0142023-01-18 16:43:49 -0800181async fn get_rkpd_attestation_key_from_registration_async(
182 registration: &Strong<dyn IRegistration>,
183 caller_uid: u32,
184) -> Result<RemotelyProvisionedKey> {
185 let (tx, rx) = oneshot::channel();
186 let cb = GetKeyCallback::new_native_binder(tx);
187
188 registration
189 .getKey(caller_uid.try_into().unwrap(), &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000190 .context(source_location_msg!("Trying to get key."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800191
192 match timeout(RKPD_TIMEOUT, rx).await {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800193 Err(e) => {
194 // Make a best effort attempt to cancel the timed out request.
195 if let Err(e) = registration.cancelGetKey(&cb) {
196 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
197 }
198 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000199 .context(source_location_msg!("Waiting for RKPD key timed out: {:?}", e))
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800200 }
Tri Vo437d0142023-01-18 16:43:49 -0800201 Ok(v) => v.unwrap(),
202 }
203}
204
Tri Voe8f04442022-12-21 08:53:56 -0800205async fn get_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000206 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800207 caller_uid: u32,
208) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000209 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800210 .await
Alice Wange66c3312023-11-07 12:41:42 +0000211 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800212 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800213}
214
Seth Moorea55428e2023-01-10 13:07:31 -0800215struct StoreUpgradedKeyCallback {
216 completer: SafeSender<Result<()>>,
217}
218
219impl StoreUpgradedKeyCallback {
220 pub fn new_native_binder(
221 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800222 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800223 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800224 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800225 }
226}
227
228impl Interface for StoreUpgradedKeyCallback {}
229
230impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
231 fn onSuccess(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800232 self.completer.send(Ok(()));
233 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800234 }
235
236 fn onError(&self, error: &str) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800237 log::error!("IGetRegistrationCallback failed: {error}");
238 self.completer.send(
Tri Vo437d0142023-01-18 16:43:49 -0800239 Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000240 .context(source_location_msg!("Failed to store upgraded key: {:?}", error)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800241 );
242 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800243 }
244}
245
Tri Vo437d0142023-01-18 16:43:49 -0800246async fn store_rkpd_attestation_key_with_registration_async(
247 registration: &Strong<dyn IRegistration>,
248 key_blob: &[u8],
249 upgraded_blob: &[u8],
250) -> Result<()> {
251 let (tx, rx) = oneshot::channel();
252 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
253
254 registration
255 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000256 .context(source_location_msg!("Failed to store upgraded blob with RKPD."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800257
258 match timeout(RKPD_TIMEOUT, rx).await {
259 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000260 .context(source_location_msg!("Waiting for RKPD to complete storing key: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800261 Ok(v) => v.unwrap(),
262 }
263}
264
Tri Voe8f04442022-12-21 08:53:56 -0800265async fn store_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000266 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800267 key_blob: &[u8],
268 upgraded_blob: &[u8],
269) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000270 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800271 .await
Alice Wange66c3312023-11-07 12:41:42 +0000272 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800273 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800274}
275
276/// Get attestation key from RKPD.
Alice Wangbf6a6932023-11-07 11:47:12 +0000277pub fn get_rkpd_attestation_key(rpc_name: &str, caller_uid: u32) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000278 tokio_rt().block_on(get_rkpd_attestation_key_async(rpc_name, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800279}
280
281/// Store attestation key in RKPD.
282pub fn store_rkpd_attestation_key(
Alice Wangbf6a6932023-11-07 11:47:12 +0000283 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800284 key_blob: &[u8],
285 upgraded_blob: &[u8],
286) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000287 tokio_rt().block_on(store_rkpd_attestation_key_async(rpc_name, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Seth Moore484010a2023-01-31 11:22:26 -0800294 use std::collections::HashMap;
Tri Vo4b1cd822023-01-23 13:05:35 -0800295 use std::sync::atomic::{AtomicU32, Ordering};
Tri Vo215f12e2023-02-15 16:23:39 -0800296 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800297
Alice Wangbf6a6932023-11-07 11:47:12 +0000298 const DEFAULT_RPC_SERVICE_NAME: &str =
299 "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
300
Tri Vo215f12e2023-02-15 16:23:39 -0800301 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800302 key: RemotelyProvisionedKey,
303 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800304 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800305 }
306
Tri Vo215f12e2023-02-15 16:23:39 -0800307 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
308
Tri Voe8f04442022-12-21 08:53:56 -0800309 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800310 pub fn new_native_binder(
311 key: &RemotelyProvisionedKey,
312 latency: Option<Duration>,
313 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800314 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800315 key: RemotelyProvisionedKey {
316 keyBlob: key.keyBlob.clone(),
317 encodedCertChain: key.encodedCertChain.clone(),
318 },
319 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800320 thread_join_handles: Vec::new(),
321 })));
Tri Voe8f04442022-12-21 08:53:56 -0800322 BnRegistration::new_binder(result, BinderFeatures::default())
323 }
324 }
325
Tri Vo215f12e2023-02-15 16:23:39 -0800326 impl Drop for MockRegistration {
327 fn drop(&mut self) {
328 let mut values = self.0.lock().unwrap();
329 for handle in values.thread_join_handles.iter_mut() {
330 // These are test threads. So, no need to worry too much about error handling.
331 handle.take().unwrap().join().unwrap();
332 }
333 }
334 }
335
Tri Voe8f04442022-12-21 08:53:56 -0800336 impl Interface for MockRegistration {}
337
338 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800339 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800340 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800341 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800342 keyBlob: values.key.keyBlob.clone(),
343 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800344 };
Tri Vo215f12e2023-02-15 16:23:39 -0800345 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800346 let get_key_cb = cb.clone();
347
348 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800349 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800350 if let Some(duration) = latency {
351 std::thread::sleep(duration);
352 }
353 get_key_cb.onSuccess(&key).unwrap();
354 });
Tri Vo215f12e2023-02-15 16:23:39 -0800355 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800356 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800357 }
358
359 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800360 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800361 }
362
Seth Moorea55428e2023-01-10 13:07:31 -0800363 fn storeUpgradedKeyAsync(
364 &self,
365 _: &[u8],
366 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800367 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800368 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800369 // We are primarily concerned with timing out correctly. Storing the key in this mock
370 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800371 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800372 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800373 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800374
375 std::thread::spawn(move || {
376 if let Some(duration) = latency {
377 std::thread::sleep(duration);
378 }
379 store_cb.onSuccess().unwrap();
380 });
381 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800382 }
383 }
384
Tri Vo437d0142023-01-18 16:43:49 -0800385 fn get_mock_registration(
386 key: &RemotelyProvisionedKey,
387 latency: Option<Duration>,
388 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800389 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800390 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800391 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800392
393 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800394 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800395 }
396
Tri Vo4b1cd822023-01-23 13:05:35 -0800397 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
398 // different test cases.
399 fn get_next_key_id() -> u32 {
400 static ID: AtomicU32 = AtomicU32::new(0);
401 ID.fetch_add(1, Ordering::Relaxed)
402 }
403
Tri Voe8f04442022-12-21 08:53:56 -0800404 #[test]
405 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800406 let key: RemotelyProvisionedKey = Default::default();
407 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800408 assert!(registration.is_ok());
409 }
410
411 #[test]
412 fn test_get_registration_cb_cancel() {
413 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800414 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800415 assert!(cb.onCancel().is_ok());
416
Tri Vo437d0142023-01-18 16:43:49 -0800417 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800418 assert_eq!(
419 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800420 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800421 );
422 }
423
424 #[test]
425 fn test_get_registration_cb_error() {
426 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800427 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800428 assert!(cb.onError("error").is_ok());
429
Tri Vo437d0142023-01-18 16:43:49 -0800430 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800431 assert_eq!(
432 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800433 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800434 );
435 }
436
437 #[test]
438 fn test_get_key_cb_success() {
439 let mock_key =
440 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
441 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800442 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800443 assert!(cb.onSuccess(&mock_key).is_ok());
444
Tri Vo437d0142023-01-18 16:43:49 -0800445 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800446 assert_eq!(key, mock_key);
447 }
448
449 #[test]
450 fn test_get_key_cb_cancel() {
451 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800452 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800453 assert!(cb.onCancel().is_ok());
454
Tri Vo437d0142023-01-18 16:43:49 -0800455 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800456 assert_eq!(
457 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800458 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800459 );
460 }
461
462 #[test]
463 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800464 let error_mapping = HashMap::from([
465 (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
466 (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
467 (
468 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
469 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
470 ),
471 (
472 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
473 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
474 ),
475 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800476
Seth Moore484010a2023-01-31 11:22:26 -0800477 // Loop over the generated list of enum values to better ensure this test stays in
478 // sync with the AIDL.
479 for get_key_error in GetKeyErrorCode::enum_values() {
480 let (tx, rx) = oneshot::channel();
481 let cb = GetKeyCallback::new_native_binder(tx);
482 assert!(cb.onError(get_key_error, "error").is_ok());
483
484 let result = tokio_rt().block_on(rx).unwrap();
485 assert_eq!(
486 result.unwrap_err().downcast::<Error>().unwrap(),
487 Error::Rc(error_mapping[&get_key_error]),
488 );
489 }
Tri Voe8f04442022-12-21 08:53:56 -0800490 }
491
492 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800493 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800494 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800495 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800496 assert!(cb.onSuccess().is_ok());
497
Tri Vo437d0142023-01-18 16:43:49 -0800498 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800499 }
500
501 #[test]
502 fn test_store_upgraded_key_cb_error() {
503 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800504 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800505 assert!(cb.onError("oh no! it failed").is_ok());
506
Tri Vo437d0142023-01-18 16:43:49 -0800507 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800508 assert_eq!(
509 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800510 Error::Rc(ResponseCode::SYSTEM_ERROR)
511 );
512 }
513
514 #[test]
515 fn test_get_mock_key_success() {
516 let mock_key =
517 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
518 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
519
520 let key = tokio_rt()
521 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
522 .unwrap();
523 assert_eq!(key, mock_key);
524 }
525
526 #[test]
527 fn test_get_mock_key_timeout() {
528 let mock_key =
529 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800530 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800531 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
532
533 let result =
534 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
535 assert_eq!(
536 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800537 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800538 );
539 }
540
541 #[test]
542 fn test_store_mock_key_success() {
543 let mock_key =
544 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
545 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
546 tokio_rt()
547 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
548 .unwrap();
549 }
550
551 #[test]
552 fn test_store_mock_key_timeout() {
553 let mock_key =
554 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800555 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800556 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
557
558 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
559 &registration,
560 &[],
561 &[],
562 ));
563 assert_eq!(
564 result.unwrap_err().downcast::<Error>().unwrap(),
565 Error::Rc(ResponseCode::SYSTEM_ERROR)
Seth Moorea55428e2023-01-10 13:07:31 -0800566 );
567 }
568
569 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800570 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800571 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800572 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000573 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800574 assert!(!key.keyBlob.is_empty());
575 assert!(!key.encodedCertChain.is_empty());
576 }
577
578 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800579 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800580 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800581 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800582
583 // Multiple calls should return the same key.
Alice Wangbf6a6932023-11-07 11:47:12 +0000584 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
585 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800586
587 assert_eq!(first_key.keyBlob, second_key.keyBlob);
588 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
589 }
590
591 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800592 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800593 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800594 let first_key_id = get_next_key_id();
595 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800596
597 // Different callers should be getting different keys.
Alice Wangbf6a6932023-11-07 11:47:12 +0000598 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, first_key_id).unwrap();
599 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800600
601 assert_ne!(first_key.keyBlob, second_key.keyBlob);
602 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
603 }
604
605 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800606 // Couple of things to note:
607 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
608 // keystore.
609 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
610 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800611 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800612 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800613 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000614 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800615 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800616
Alice Wangbf6a6932023-11-07 11:47:12 +0000617 assert!(
618 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &key.keyBlob, &new_blob).is_ok()
619 );
Tri Vobac3b522023-01-23 13:10:24 -0800620
Alice Wangbf6a6932023-11-07 11:47:12 +0000621 let new_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800622
623 // Restore original key so that we don't leave RKPD with invalid blobs.
Alice Wangbf6a6932023-11-07 11:47:12 +0000624 assert!(
625 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &new_blob, &key.keyBlob).is_ok()
626 );
Tri Vobac3b522023-01-23 13:10:24 -0800627 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800628 }
Tri Vo30268da2023-01-24 15:35:45 -0800629
630 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800631 fn test_stress_get_rkpd_attestation_key() {
632 binder::ProcessState::start_thread_pool();
633 let key_id = get_next_key_id();
634 let mut threads = vec![];
635 const NTHREADS: u32 = 10;
636 const NCALLS: u32 = 1000;
637
638 for _ in 0..NTHREADS {
639 threads.push(std::thread::spawn(move || {
640 for _ in 0..NCALLS {
Alice Wangbf6a6932023-11-07 11:47:12 +0000641 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vo02f0fa42023-01-24 12:32:08 -0800642 assert!(!key.keyBlob.is_empty());
643 assert!(!key.encodedCertChain.is_empty());
644 }
645 }));
646 }
647
648 for t in threads {
649 assert!(t.join().is_ok());
650 }
651 }
Tri Voe8f04442022-12-21 08:53:56 -0800652}