blob: 986883827e650fe769ab27d11738fb7370fcd4ee [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
Tri Voe8f04442022-12-21 08:53:56 -080017use android_security_rkp_aidl::aidl::android::security::rkp::{
Seth Moore484010a2023-01-31 11:22:26 -080018 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
19 IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
Tri Voe8f04442022-12-21 08:53:56 -080020 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
Seth Moorea55428e2023-01-10 13:07:31 -080021 IRemoteProvisioning::IRemoteProvisioning,
22 IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
23 IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
24 RemotelyProvisionedKey::RemotelyProvisionedKey,
Tri Voe8f04442022-12-21 08:53:56 -080025};
Tri Voe8f04442022-12-21 08:53:56 -080026use anyhow::{Context, Result};
Alice Wang2dbabf32023-11-08 10:43:21 +000027use binder::{BinderFeatures, Interface, StatusCode, Strong};
Alice Wange66c3312023-11-07 12:41:42 +000028use message_macro::source_location_msg;
Tri Voe8f04442022-12-21 08:53:56 -080029use std::sync::Mutex;
Tri Vo437d0142023-01-18 16:43:49 -080030use std::time::Duration;
31use tokio::sync::oneshot;
32use tokio::time::timeout;
33
34// Normally, we block indefinitely when making calls outside of keystore and rely on watchdog to
35// report deadlocks. However, RKPD is mainline updatable. Also, calls to RKPD may wait on network
36// for certificates. So, we err on the side of caution and timeout instead.
37static RKPD_TIMEOUT: Duration = Duration::from_secs(10);
38
39fn tokio_rt() -> tokio::runtime::Runtime {
40 tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
41}
Tri Voe8f04442022-12-21 08:53:56 -080042
Alice Wang2dbabf32023-11-08 10:43:21 +000043/// Errors occurred during the interaction with RKPD.
44#[derive(Debug, Clone, Copy, thiserror::Error, PartialEq, Eq)]
45pub enum Error {
46 /// An RKPD request gets cancelled.
47 #[error("An RKPD request gets cancelled")]
48 RequestCancelled,
49
50 /// Failed to get registration.
51 #[error("Failed to get registration")]
52 GetRegistrationFailed,
53
54 /// Failed to get key.
55 #[error("Failed to get key: {0:?}")]
56 GetKeyFailed(GetKeyErrorCode),
57
58 /// Failed to store upgraded key.
59 #[error("Failed to store upgraded key")]
60 StoreUpgradedKeyFailed,
61
62 /// Timeout when waiting for a callback.
63 #[error("Timeout when waiting for a callback")]
64 Timeout,
65
66 /// Wraps a Binder status code.
67 #[error("Binder transaction error {0:?}")]
68 BinderTransaction(StatusCode),
69}
70
71impl From<StatusCode> for Error {
72 fn from(s: StatusCode) -> Self {
73 Self::BinderTransaction(s)
74 }
75}
76
Seth Moorea882c962023-01-09 16:55:10 -080077/// Thread-safe channel for sending a value once and only once. If a value has
78/// already been send, subsequent calls to send will noop.
79struct SafeSender<T> {
80 inner: Mutex<Option<oneshot::Sender<T>>>,
81}
82
83impl<T> SafeSender<T> {
84 fn new(sender: oneshot::Sender<T>) -> Self {
85 Self { inner: Mutex::new(Some(sender)) }
86 }
87
88 fn send(&self, value: T) {
89 if let Some(inner) = self.inner.lock().unwrap().take() {
Tri Vo0e5fe2c2023-02-15 17:02:06 -080090 // It's possible for the corresponding receiver to time out and be dropped. In this
91 // case send() will fail. This error is not actionable though, so only log the error.
92 if inner.send(value).is_err() {
93 log::error!("SafeSender::send() failed");
94 }
Seth Moorea882c962023-01-09 16:55:10 -080095 }
96 }
97}
Tri Voe8f04442022-12-21 08:53:56 -080098
99struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800100 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800101}
102
103impl GetRegistrationCallback {
104 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -0800105 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800106 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -0800107 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -0800108 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800109 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800110 }
111}
112
113impl Interface for GetRegistrationCallback {}
114
115impl IGetRegistrationCallback for GetRegistrationCallback {
116 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800117 self.registration_tx.send(Ok(registration.clone()));
118 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800119 }
120 fn onCancel(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800121 log::warn!("IGetRegistrationCallback cancelled");
122 self.registration_tx.send(
Alice Wang2dbabf32023-11-08 10:43:21 +0000123 Err(Error::RequestCancelled)
Alice Wange66c3312023-11-07 12:41:42 +0000124 .context(source_location_msg!("GetRegistrationCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800125 );
126 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800127 }
Seth Moore484010a2023-01-31 11:22:26 -0800128 fn onError(&self, description: &str) -> binder::Result<()> {
Seth Moore484010a2023-01-31 11:22:26 -0800129 log::error!("IGetRegistrationCallback failed: '{description}'");
Alice Wang2dbabf32023-11-08 10:43:21 +0000130 self.registration_tx.send(
131 Err(Error::GetRegistrationFailed)
132 .context(source_location_msg!("GetRegistrationCallback failed: {:?}", description)),
133 );
Seth Moore613a1fd2023-01-11 10:42:26 -0800134 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800135 }
136}
137
138/// Make a new connection to a IRegistration service.
Alice Wangbf6a6932023-11-07 11:47:12 +0000139async fn get_rkpd_registration(rpc_name: &str) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800140 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
Alice Wang2dbabf32023-11-08 10:43:21 +0000141 binder::get_interface("remote_provisioning")
142 .map_err(Error::from)
Alice Wange66c3312023-11-07 12:41:42 +0000143 .context(source_location_msg!("Trying to connect to IRemoteProvisioning service."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800144
Tri Voe8f04442022-12-21 08:53:56 -0800145 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800146 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800147
148 remote_provisioning
Alice Wangbf6a6932023-11-07 11:47:12 +0000149 .getRegistration(rpc_name, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000150 .context(source_location_msg!("Trying to get registration."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800151
Tri Vo437d0142023-01-18 16:43:49 -0800152 match timeout(RKPD_TIMEOUT, rx).await {
Alice Wang2dbabf32023-11-08 10:43:21 +0000153 Err(e) => Err(Error::Timeout).context(source_location_msg!("Waiting for RKPD: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800154 Ok(v) => v.unwrap(),
155 }
Tri Voe8f04442022-12-21 08:53:56 -0800156}
157
Tri Voe8f04442022-12-21 08:53:56 -0800158struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800159 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800160}
161
162impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800163 pub fn new_native_binder(
164 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800165 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800166 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800167 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800168 }
169}
170
171impl Interface for GetKeyCallback {}
172
173impl IGetKeyCallback for GetKeyCallback {
174 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800175 self.key_tx.send(Ok(RemotelyProvisionedKey {
176 keyBlob: key.keyBlob.clone(),
177 encodedCertChain: key.encodedCertChain.clone(),
178 }));
179 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800180 }
181 fn onCancel(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800182 log::warn!("IGetKeyCallback cancelled");
183 self.key_tx.send(
Alice Wang2dbabf32023-11-08 10:43:21 +0000184 Err(Error::RequestCancelled).context(source_location_msg!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800185 );
186 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800187 }
Seth Moore484010a2023-01-31 11:22:26 -0800188 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Seth Moore484010a2023-01-31 11:22:26 -0800189 log::error!("IGetKeyCallback failed: {description}");
Alice Wang2dbabf32023-11-08 10:43:21 +0000190 self.key_tx.send(Err(Error::GetKeyFailed(error)).context(source_location_msg!(
Seth Moore484010a2023-01-31 11:22:26 -0800191 "GetKeyCallback failed: {:?} {:?}",
192 error,
193 description
194 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800195 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800196 }
197}
198
Tri Vo437d0142023-01-18 16:43:49 -0800199async fn get_rkpd_attestation_key_from_registration_async(
200 registration: &Strong<dyn IRegistration>,
201 caller_uid: u32,
202) -> Result<RemotelyProvisionedKey> {
203 let (tx, rx) = oneshot::channel();
204 let cb = GetKeyCallback::new_native_binder(tx);
205
206 registration
207 .getKey(caller_uid.try_into().unwrap(), &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000208 .context(source_location_msg!("Trying to get key."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800209
210 match timeout(RKPD_TIMEOUT, rx).await {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800211 Err(e) => {
212 // Make a best effort attempt to cancel the timed out request.
213 if let Err(e) = registration.cancelGetKey(&cb) {
214 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
215 }
Alice Wang2dbabf32023-11-08 10:43:21 +0000216 Err(Error::Timeout)
Alice Wange66c3312023-11-07 12:41:42 +0000217 .context(source_location_msg!("Waiting for RKPD key timed out: {:?}", e))
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800218 }
Tri Vo437d0142023-01-18 16:43:49 -0800219 Ok(v) => v.unwrap(),
220 }
221}
222
Tri Voe8f04442022-12-21 08:53:56 -0800223async fn get_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000224 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800225 caller_uid: u32,
226) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000227 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800228 .await
Alice Wange66c3312023-11-07 12:41:42 +0000229 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800230 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800231}
232
Seth Moorea55428e2023-01-10 13:07:31 -0800233struct StoreUpgradedKeyCallback {
234 completer: SafeSender<Result<()>>,
235}
236
237impl StoreUpgradedKeyCallback {
238 pub fn new_native_binder(
239 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800240 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800241 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800242 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800243 }
244}
245
246impl Interface for StoreUpgradedKeyCallback {}
247
248impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
249 fn onSuccess(&self) -> binder::Result<()> {
Seth Moore613a1fd2023-01-11 10:42:26 -0800250 self.completer.send(Ok(()));
251 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800252 }
253
254 fn onError(&self, error: &str) -> binder::Result<()> {
Alice Wang2dbabf32023-11-08 10:43:21 +0000255 log::error!("IStoreUpgradedKeyCallback failed: {error}");
Seth Moore613a1fd2023-01-11 10:42:26 -0800256 self.completer.send(
Alice Wang2dbabf32023-11-08 10:43:21 +0000257 Err(Error::StoreUpgradedKeyFailed)
Alice Wange66c3312023-11-07 12:41:42 +0000258 .context(source_location_msg!("Failed to store upgraded key: {:?}", error)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800259 );
260 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800261 }
262}
263
Tri Vo437d0142023-01-18 16:43:49 -0800264async fn store_rkpd_attestation_key_with_registration_async(
265 registration: &Strong<dyn IRegistration>,
266 key_blob: &[u8],
267 upgraded_blob: &[u8],
268) -> Result<()> {
269 let (tx, rx) = oneshot::channel();
270 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
271
272 registration
273 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000274 .context(source_location_msg!("Failed to store upgraded blob with RKPD."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800275
276 match timeout(RKPD_TIMEOUT, rx).await {
Alice Wang2dbabf32023-11-08 10:43:21 +0000277 Err(e) => Err(Error::Timeout)
Alice Wange66c3312023-11-07 12:41:42 +0000278 .context(source_location_msg!("Waiting for RKPD to complete storing key: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800279 Ok(v) => v.unwrap(),
280 }
281}
282
Tri Voe8f04442022-12-21 08:53:56 -0800283async fn store_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000284 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800285 key_blob: &[u8],
286 upgraded_blob: &[u8],
287) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000288 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800289 .await
Alice Wange66c3312023-11-07 12:41:42 +0000290 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800291 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800292}
293
294/// Get attestation key from RKPD.
Alice Wangbf6a6932023-11-07 11:47:12 +0000295pub fn get_rkpd_attestation_key(rpc_name: &str, caller_uid: u32) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000296 tokio_rt().block_on(get_rkpd_attestation_key_async(rpc_name, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800297}
298
299/// Store attestation key in RKPD.
300pub fn store_rkpd_attestation_key(
Alice Wangbf6a6932023-11-07 11:47:12 +0000301 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800302 key_blob: &[u8],
303 upgraded_blob: &[u8],
304) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000305 tokio_rt().block_on(store_rkpd_attestation_key_async(rpc_name, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800306}
307
308#[cfg(test)]
309mod tests {
310 use super::*;
311 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Tri Vo4b1cd822023-01-23 13:05:35 -0800312 use std::sync::atomic::{AtomicU32, Ordering};
Tri Vo215f12e2023-02-15 16:23:39 -0800313 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800314
Alice Wangbf6a6932023-11-07 11:47:12 +0000315 const DEFAULT_RPC_SERVICE_NAME: &str =
316 "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
317
Tri Vo215f12e2023-02-15 16:23:39 -0800318 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800319 key: RemotelyProvisionedKey,
320 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800321 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800322 }
323
Tri Vo215f12e2023-02-15 16:23:39 -0800324 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
325
Tri Voe8f04442022-12-21 08:53:56 -0800326 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800327 pub fn new_native_binder(
328 key: &RemotelyProvisionedKey,
329 latency: Option<Duration>,
330 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800331 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800332 key: RemotelyProvisionedKey {
333 keyBlob: key.keyBlob.clone(),
334 encodedCertChain: key.encodedCertChain.clone(),
335 },
336 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800337 thread_join_handles: Vec::new(),
338 })));
Tri Voe8f04442022-12-21 08:53:56 -0800339 BnRegistration::new_binder(result, BinderFeatures::default())
340 }
341 }
342
Tri Vo215f12e2023-02-15 16:23:39 -0800343 impl Drop for MockRegistration {
344 fn drop(&mut self) {
345 let mut values = self.0.lock().unwrap();
346 for handle in values.thread_join_handles.iter_mut() {
347 // These are test threads. So, no need to worry too much about error handling.
348 handle.take().unwrap().join().unwrap();
349 }
350 }
351 }
352
Tri Voe8f04442022-12-21 08:53:56 -0800353 impl Interface for MockRegistration {}
354
355 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800356 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800357 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800358 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800359 keyBlob: values.key.keyBlob.clone(),
360 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800361 };
Tri Vo215f12e2023-02-15 16:23:39 -0800362 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800363 let get_key_cb = cb.clone();
364
365 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800366 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800367 if let Some(duration) = latency {
368 std::thread::sleep(duration);
369 }
370 get_key_cb.onSuccess(&key).unwrap();
371 });
Tri Vo215f12e2023-02-15 16:23:39 -0800372 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800373 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800374 }
375
376 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800377 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800378 }
379
Seth Moorea55428e2023-01-10 13:07:31 -0800380 fn storeUpgradedKeyAsync(
381 &self,
382 _: &[u8],
383 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800384 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800385 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800386 // We are primarily concerned with timing out correctly. Storing the key in this mock
387 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800388 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800389 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800390 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800391
392 std::thread::spawn(move || {
393 if let Some(duration) = latency {
394 std::thread::sleep(duration);
395 }
396 store_cb.onSuccess().unwrap();
397 });
398 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800399 }
400 }
401
Tri Vo437d0142023-01-18 16:43:49 -0800402 fn get_mock_registration(
403 key: &RemotelyProvisionedKey,
404 latency: Option<Duration>,
405 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800406 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800407 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800408 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800409
410 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800411 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800412 }
413
Tri Vo4b1cd822023-01-23 13:05:35 -0800414 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
415 // different test cases.
416 fn get_next_key_id() -> u32 {
417 static ID: AtomicU32 = AtomicU32::new(0);
418 ID.fetch_add(1, Ordering::Relaxed)
419 }
420
Tri Voe8f04442022-12-21 08:53:56 -0800421 #[test]
422 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800423 let key: RemotelyProvisionedKey = Default::default();
424 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800425 assert!(registration.is_ok());
426 }
427
428 #[test]
429 fn test_get_registration_cb_cancel() {
430 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800431 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800432 assert!(cb.onCancel().is_ok());
433
Tri Vo437d0142023-01-18 16:43:49 -0800434 let result = tokio_rt().block_on(rx).unwrap();
Alice Wang2dbabf32023-11-08 10:43:21 +0000435 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::RequestCancelled);
Tri Voe8f04442022-12-21 08:53:56 -0800436 }
437
438 #[test]
439 fn test_get_registration_cb_error() {
440 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800441 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800442 assert!(cb.onError("error").is_ok());
443
Tri Vo437d0142023-01-18 16:43:49 -0800444 let result = tokio_rt().block_on(rx).unwrap();
Alice Wang2dbabf32023-11-08 10:43:21 +0000445 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::GetRegistrationFailed);
Tri Voe8f04442022-12-21 08:53:56 -0800446 }
447
448 #[test]
449 fn test_get_key_cb_success() {
450 let mock_key =
451 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
452 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800453 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800454 assert!(cb.onSuccess(&mock_key).is_ok());
455
Tri Vo437d0142023-01-18 16:43:49 -0800456 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800457 assert_eq!(key, mock_key);
458 }
459
460 #[test]
461 fn test_get_key_cb_cancel() {
462 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800463 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800464 assert!(cb.onCancel().is_ok());
465
Tri Vo437d0142023-01-18 16:43:49 -0800466 let result = tokio_rt().block_on(rx).unwrap();
Alice Wang2dbabf32023-11-08 10:43:21 +0000467 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::RequestCancelled);
Tri Voe8f04442022-12-21 08:53:56 -0800468 }
469
470 #[test]
471 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800472 for get_key_error in GetKeyErrorCode::enum_values() {
473 let (tx, rx) = oneshot::channel();
474 let cb = GetKeyCallback::new_native_binder(tx);
475 assert!(cb.onError(get_key_error, "error").is_ok());
476
477 let result = tokio_rt().block_on(rx).unwrap();
478 assert_eq!(
479 result.unwrap_err().downcast::<Error>().unwrap(),
Alice Wang2dbabf32023-11-08 10:43:21 +0000480 Error::GetKeyFailed(get_key_error),
Seth Moore484010a2023-01-31 11:22:26 -0800481 );
482 }
Tri Voe8f04442022-12-21 08:53:56 -0800483 }
484
485 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800486 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800487 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800488 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800489 assert!(cb.onSuccess().is_ok());
490
Tri Vo437d0142023-01-18 16:43:49 -0800491 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800492 }
493
494 #[test]
495 fn test_store_upgraded_key_cb_error() {
496 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800497 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800498 assert!(cb.onError("oh no! it failed").is_ok());
499
Tri Vo437d0142023-01-18 16:43:49 -0800500 let result = tokio_rt().block_on(rx).unwrap();
Alice Wang2dbabf32023-11-08 10:43:21 +0000501 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::StoreUpgradedKeyFailed);
Tri Vo437d0142023-01-18 16:43:49 -0800502 }
503
504 #[test]
505 fn test_get_mock_key_success() {
506 let mock_key =
507 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
508 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
509
510 let key = tokio_rt()
511 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
512 .unwrap();
513 assert_eq!(key, mock_key);
514 }
515
516 #[test]
517 fn test_get_mock_key_timeout() {
518 let mock_key =
519 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800520 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800521 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
522
523 let result =
524 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
Alice Wang2dbabf32023-11-08 10:43:21 +0000525 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::Timeout);
Tri Vo437d0142023-01-18 16:43:49 -0800526 }
527
528 #[test]
529 fn test_store_mock_key_success() {
530 let mock_key =
531 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
532 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
533 tokio_rt()
534 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
535 .unwrap();
536 }
537
538 #[test]
539 fn test_store_mock_key_timeout() {
540 let mock_key =
541 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800542 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800543 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
544
545 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
546 &registration,
547 &[],
548 &[],
549 ));
Alice Wang2dbabf32023-11-08 10:43:21 +0000550 assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::Timeout);
Seth Moorea55428e2023-01-10 13:07:31 -0800551 }
552
553 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800554 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800555 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800556 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000557 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800558 assert!(!key.keyBlob.is_empty());
559 assert!(!key.encodedCertChain.is_empty());
560 }
561
562 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800563 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800564 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800565 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800566
567 // Multiple calls should return the same key.
Alice Wangbf6a6932023-11-07 11:47:12 +0000568 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
569 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800570
571 assert_eq!(first_key.keyBlob, second_key.keyBlob);
572 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
573 }
574
575 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800576 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800577 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800578 let first_key_id = get_next_key_id();
579 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800580
581 // Different callers should be getting different keys.
Alice Wangbf6a6932023-11-07 11:47:12 +0000582 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, first_key_id).unwrap();
583 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800584
585 assert_ne!(first_key.keyBlob, second_key.keyBlob);
586 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
587 }
588
589 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800590 // Couple of things to note:
591 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
592 // keystore.
593 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
594 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800595 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800596 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800597 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000598 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800599 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800600
Alice Wangbf6a6932023-11-07 11:47:12 +0000601 assert!(
602 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &key.keyBlob, &new_blob).is_ok()
603 );
Tri Vobac3b522023-01-23 13:10:24 -0800604
Alice Wangbf6a6932023-11-07 11:47:12 +0000605 let new_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800606
607 // Restore original key so that we don't leave RKPD with invalid blobs.
Alice Wangbf6a6932023-11-07 11:47:12 +0000608 assert!(
609 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &new_blob, &key.keyBlob).is_ok()
610 );
Tri Vobac3b522023-01-23 13:10:24 -0800611 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800612 }
Tri Vo30268da2023-01-24 15:35:45 -0800613
614 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800615 fn test_stress_get_rkpd_attestation_key() {
616 binder::ProcessState::start_thread_pool();
617 let key_id = get_next_key_id();
618 let mut threads = vec![];
619 const NTHREADS: u32 = 10;
620 const NCALLS: u32 = 1000;
621
622 for _ in 0..NTHREADS {
623 threads.push(std::thread::spawn(move || {
624 for _ in 0..NCALLS {
Alice Wangbf6a6932023-11-07 11:47:12 +0000625 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vo02f0fa42023-01-24 12:32:08 -0800626 assert!(!key.keyBlob.is_empty());
627 assert!(!key.encodedCertChain.is_empty());
628 }
629 }));
630 }
631
632 for t in threads {
633 assert!(t.join().is_ok());
634 }
635 }
Tri Voe8f04442022-12-21 08:53:56 -0800636}