blob: 931782477a365151f8732800a8bcd6f4043e241f [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};
Alice Wang83c6aef2023-11-03 17:17:34 +000018use crate::watchdog_helper::watchdog as wd;
Tri Voe8f04442022-12-21 08:53:56 -080019use android_security_rkp_aidl::aidl::android::security::rkp::{
Seth Moore484010a2023-01-31 11:22:26 -080020 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
21 IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
Tri Voe8f04442022-12-21 08:53:56 -080022 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
Seth Moorea55428e2023-01-10 13:07:31 -080023 IRemoteProvisioning::IRemoteProvisioning,
24 IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
25 IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
26 RemotelyProvisionedKey::RemotelyProvisionedKey,
Tri Voe8f04442022-12-21 08:53:56 -080027};
28use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
29use anyhow::{Context, Result};
Alice Wange66c3312023-11-07 12:41:42 +000030use message_macro::source_location_msg;
Tri Voe8f04442022-12-21 08:53:56 -080031use std::sync::Mutex;
Tri Vo437d0142023-01-18 16:43:49 -080032use std::time::Duration;
33use tokio::sync::oneshot;
34use tokio::time::timeout;
35
36// Normally, we block indefinitely when making calls outside of keystore and rely on watchdog to
37// report deadlocks. However, RKPD is mainline updatable. Also, calls to RKPD may wait on network
38// for certificates. So, we err on the side of caution and timeout instead.
39static RKPD_TIMEOUT: Duration = Duration::from_secs(10);
40
41fn tokio_rt() -> tokio::runtime::Runtime {
42 tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
43}
Tri Voe8f04442022-12-21 08:53:56 -080044
Seth Moorea882c962023-01-09 16:55:10 -080045/// Thread-safe channel for sending a value once and only once. If a value has
46/// already been send, subsequent calls to send will noop.
47struct SafeSender<T> {
48 inner: Mutex<Option<oneshot::Sender<T>>>,
49}
50
51impl<T> SafeSender<T> {
52 fn new(sender: oneshot::Sender<T>) -> Self {
53 Self { inner: Mutex::new(Some(sender)) }
54 }
55
56 fn send(&self, value: T) {
57 if let Some(inner) = self.inner.lock().unwrap().take() {
Tri Vo0e5fe2c2023-02-15 17:02:06 -080058 // It's possible for the corresponding receiver to time out and be dropped. In this
59 // case send() will fail. This error is not actionable though, so only log the error.
60 if inner.send(value).is_err() {
61 log::error!("SafeSender::send() failed");
62 }
Seth Moorea882c962023-01-09 16:55:10 -080063 }
64 }
65}
Tri Voe8f04442022-12-21 08:53:56 -080066
67struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080068 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080069}
70
71impl GetRegistrationCallback {
72 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080073 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -080074 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -080075 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080076 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -080077 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -080078 }
79}
80
81impl Interface for GetRegistrationCallback {}
82
83impl IGetRegistrationCallback for GetRegistrationCallback {
84 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
85 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080086 self.registration_tx.send(Ok(registration.clone()));
87 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080088 }
89 fn onCancel(&self) -> binder::Result<()> {
90 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080091 log::warn!("IGetRegistrationCallback cancelled");
92 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -080093 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +000094 .context(source_location_msg!("GetRegistrationCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -080095 );
96 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080097 }
Seth Moore484010a2023-01-31 11:22:26 -080098 fn onError(&self, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -080099 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800100 log::error!("IGetRegistrationCallback failed: '{description}'");
Alice Wange66c3312023-11-07 12:41:42 +0000101 self.registration_tx
102 .send(Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)).context(
103 source_location_msg!("GetRegistrationCallback failed: {:?}", description),
104 ));
Seth Moore613a1fd2023-01-11 10:42:26 -0800105 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800106 }
107}
108
109/// Make a new connection to a IRegistration service.
Alice Wangbf6a6932023-11-07 11:47:12 +0000110async fn get_rkpd_registration(rpc_name: &str) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800111 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
112 map_binder_status_code(binder::get_interface("remote_provisioning"))
Alice Wange66c3312023-11-07 12:41:42 +0000113 .context(source_location_msg!("Trying to connect to IRemoteProvisioning service."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800114
Tri Voe8f04442022-12-21 08:53:56 -0800115 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800116 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800117
118 remote_provisioning
Alice Wangbf6a6932023-11-07 11:47:12 +0000119 .getRegistration(rpc_name, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000120 .context(source_location_msg!("Trying to get registration."))?;
Tri Voe8f04442022-12-21 08:53:56 -0800121
Tri Vo437d0142023-01-18 16:43:49 -0800122 match timeout(RKPD_TIMEOUT, rx).await {
Alice Wange66c3312023-11-07 12:41:42 +0000123 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
124 .context(source_location_msg!("Waiting for RKPD: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800125 Ok(v) => v.unwrap(),
126 }
Tri Voe8f04442022-12-21 08:53:56 -0800127}
128
Tri Voe8f04442022-12-21 08:53:56 -0800129struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800130 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800131}
132
133impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800134 pub fn new_native_binder(
135 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800136 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800137 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800138 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800139 }
140}
141
142impl Interface for GetKeyCallback {}
143
144impl IGetKeyCallback for GetKeyCallback {
145 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
146 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800147 self.key_tx.send(Ok(RemotelyProvisionedKey {
148 keyBlob: key.keyBlob.clone(),
149 encodedCertChain: key.encodedCertChain.clone(),
150 }));
151 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800152 }
153 fn onCancel(&self) -> binder::Result<()> {
154 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800155 log::warn!("IGetKeyCallback cancelled");
156 self.key_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800157 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000158 .context(source_location_msg!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800159 );
160 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800161 }
Seth Moore484010a2023-01-31 11:22:26 -0800162 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800163 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800164 log::error!("IGetKeyCallback failed: {description}");
165 let rc = match error {
166 GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
167 GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
168 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
169 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
170 }
171 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
172 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
173 }
174 _ => {
175 log::error!("Unexpected error from rkpd: {error:?}");
176 ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
177 }
178 };
Alice Wange66c3312023-11-07 12:41:42 +0000179 self.key_tx.send(Err(Error::Rc(rc)).context(source_location_msg!(
Seth Moore484010a2023-01-31 11:22:26 -0800180 "GetKeyCallback failed: {:?} {:?}",
181 error,
182 description
183 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800184 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800185 }
186}
187
Tri Vo437d0142023-01-18 16:43:49 -0800188async fn get_rkpd_attestation_key_from_registration_async(
189 registration: &Strong<dyn IRegistration>,
190 caller_uid: u32,
191) -> Result<RemotelyProvisionedKey> {
192 let (tx, rx) = oneshot::channel();
193 let cb = GetKeyCallback::new_native_binder(tx);
194
195 registration
196 .getKey(caller_uid.try_into().unwrap(), &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000197 .context(source_location_msg!("Trying to get key."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800198
199 match timeout(RKPD_TIMEOUT, rx).await {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800200 Err(e) => {
201 // Make a best effort attempt to cancel the timed out request.
202 if let Err(e) = registration.cancelGetKey(&cb) {
203 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
204 }
205 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000206 .context(source_location_msg!("Waiting for RKPD key timed out: {:?}", e))
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800207 }
Tri Vo437d0142023-01-18 16:43:49 -0800208 Ok(v) => v.unwrap(),
209 }
210}
211
Tri Voe8f04442022-12-21 08:53:56 -0800212async fn get_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000213 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800214 caller_uid: u32,
215) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000216 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800217 .await
Alice Wange66c3312023-11-07 12:41:42 +0000218 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800219 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800220}
221
Seth Moorea55428e2023-01-10 13:07:31 -0800222struct StoreUpgradedKeyCallback {
223 completer: SafeSender<Result<()>>,
224}
225
226impl StoreUpgradedKeyCallback {
227 pub fn new_native_binder(
228 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800229 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800230 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800231 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800232 }
233}
234
235impl Interface for StoreUpgradedKeyCallback {}
236
237impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
238 fn onSuccess(&self) -> binder::Result<()> {
239 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800240 self.completer.send(Ok(()));
241 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800242 }
243
244 fn onError(&self, error: &str) -> binder::Result<()> {
245 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800246 log::error!("IGetRegistrationCallback failed: {error}");
247 self.completer.send(
Tri Vo437d0142023-01-18 16:43:49 -0800248 Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000249 .context(source_location_msg!("Failed to store upgraded key: {:?}", error)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800250 );
251 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800252 }
253}
254
Tri Vo437d0142023-01-18 16:43:49 -0800255async fn store_rkpd_attestation_key_with_registration_async(
256 registration: &Strong<dyn IRegistration>,
257 key_blob: &[u8],
258 upgraded_blob: &[u8],
259) -> Result<()> {
260 let (tx, rx) = oneshot::channel();
261 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
262
263 registration
264 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
Alice Wange66c3312023-11-07 12:41:42 +0000265 .context(source_location_msg!("Failed to store upgraded blob with RKPD."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800266
267 match timeout(RKPD_TIMEOUT, rx).await {
268 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Alice Wange66c3312023-11-07 12:41:42 +0000269 .context(source_location_msg!("Waiting for RKPD to complete storing key: {:?}", e)),
Tri Vo437d0142023-01-18 16:43:49 -0800270 Ok(v) => v.unwrap(),
271 }
272}
273
Tri Voe8f04442022-12-21 08:53:56 -0800274async fn store_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000275 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800276 key_blob: &[u8],
277 upgraded_blob: &[u8],
278) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000279 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800280 .await
Alice Wange66c3312023-11-07 12:41:42 +0000281 .context(source_location_msg!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800282 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800283}
284
285/// Get attestation key from RKPD.
Alice Wangbf6a6932023-11-07 11:47:12 +0000286pub fn get_rkpd_attestation_key(rpc_name: &str, caller_uid: u32) -> Result<RemotelyProvisionedKey> {
Tri Voe8f04442022-12-21 08:53:56 -0800287 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
Alice Wangbf6a6932023-11-07 11:47:12 +0000288 tokio_rt().block_on(get_rkpd_attestation_key_async(rpc_name, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800289}
290
291/// Store attestation key in RKPD.
292pub fn store_rkpd_attestation_key(
Alice Wangbf6a6932023-11-07 11:47:12 +0000293 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800294 key_blob: &[u8],
295 upgraded_blob: &[u8],
296) -> Result<()> {
297 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
Alice Wangbf6a6932023-11-07 11:47:12 +0000298 tokio_rt().block_on(store_rkpd_attestation_key_async(rpc_name, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800299}
300
301#[cfg(test)]
302mod tests {
303 use super::*;
304 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Seth Moore484010a2023-01-31 11:22:26 -0800305 use std::collections::HashMap;
Tri Vo4b1cd822023-01-23 13:05:35 -0800306 use std::sync::atomic::{AtomicU32, Ordering};
Tri Vo215f12e2023-02-15 16:23:39 -0800307 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800308
Alice Wangbf6a6932023-11-07 11:47:12 +0000309 const DEFAULT_RPC_SERVICE_NAME: &str =
310 "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
311
Tri Vo215f12e2023-02-15 16:23:39 -0800312 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800313 key: RemotelyProvisionedKey,
314 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800315 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800316 }
317
Tri Vo215f12e2023-02-15 16:23:39 -0800318 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
319
Tri Voe8f04442022-12-21 08:53:56 -0800320 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800321 pub fn new_native_binder(
322 key: &RemotelyProvisionedKey,
323 latency: Option<Duration>,
324 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800325 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800326 key: RemotelyProvisionedKey {
327 keyBlob: key.keyBlob.clone(),
328 encodedCertChain: key.encodedCertChain.clone(),
329 },
330 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800331 thread_join_handles: Vec::new(),
332 })));
Tri Voe8f04442022-12-21 08:53:56 -0800333 BnRegistration::new_binder(result, BinderFeatures::default())
334 }
335 }
336
Tri Vo215f12e2023-02-15 16:23:39 -0800337 impl Drop for MockRegistration {
338 fn drop(&mut self) {
339 let mut values = self.0.lock().unwrap();
340 for handle in values.thread_join_handles.iter_mut() {
341 // These are test threads. So, no need to worry too much about error handling.
342 handle.take().unwrap().join().unwrap();
343 }
344 }
345 }
346
Tri Voe8f04442022-12-21 08:53:56 -0800347 impl Interface for MockRegistration {}
348
349 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800350 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800351 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800352 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800353 keyBlob: values.key.keyBlob.clone(),
354 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800355 };
Tri Vo215f12e2023-02-15 16:23:39 -0800356 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800357 let get_key_cb = cb.clone();
358
359 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800360 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800361 if let Some(duration) = latency {
362 std::thread::sleep(duration);
363 }
364 get_key_cb.onSuccess(&key).unwrap();
365 });
Tri Vo215f12e2023-02-15 16:23:39 -0800366 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800367 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800368 }
369
370 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800371 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800372 }
373
Seth Moorea55428e2023-01-10 13:07:31 -0800374 fn storeUpgradedKeyAsync(
375 &self,
376 _: &[u8],
377 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800378 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800379 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800380 // We are primarily concerned with timing out correctly. Storing the key in this mock
381 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800382 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800383 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800384 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800385
386 std::thread::spawn(move || {
387 if let Some(duration) = latency {
388 std::thread::sleep(duration);
389 }
390 store_cb.onSuccess().unwrap();
391 });
392 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800393 }
394 }
395
Tri Vo437d0142023-01-18 16:43:49 -0800396 fn get_mock_registration(
397 key: &RemotelyProvisionedKey,
398 latency: Option<Duration>,
399 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800400 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800401 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800402 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800403
404 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800405 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800406 }
407
Tri Vo4b1cd822023-01-23 13:05:35 -0800408 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
409 // different test cases.
410 fn get_next_key_id() -> u32 {
411 static ID: AtomicU32 = AtomicU32::new(0);
412 ID.fetch_add(1, Ordering::Relaxed)
413 }
414
Tri Voe8f04442022-12-21 08:53:56 -0800415 #[test]
416 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800417 let key: RemotelyProvisionedKey = Default::default();
418 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800419 assert!(registration.is_ok());
420 }
421
422 #[test]
423 fn test_get_registration_cb_cancel() {
424 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800425 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800426 assert!(cb.onCancel().is_ok());
427
Tri Vo437d0142023-01-18 16:43:49 -0800428 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800429 assert_eq!(
430 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800431 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800432 );
433 }
434
435 #[test]
436 fn test_get_registration_cb_error() {
437 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800438 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800439 assert!(cb.onError("error").is_ok());
440
Tri Vo437d0142023-01-18 16:43:49 -0800441 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800442 assert_eq!(
443 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800444 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800445 );
446 }
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();
Tri Voe8f04442022-12-21 08:53:56 -0800467 assert_eq!(
468 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800469 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800470 );
471 }
472
473 #[test]
474 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800475 let error_mapping = HashMap::from([
476 (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
477 (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
478 (
479 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
480 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
481 ),
482 (
483 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
484 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
485 ),
486 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800487
Seth Moore484010a2023-01-31 11:22:26 -0800488 // Loop over the generated list of enum values to better ensure this test stays in
489 // sync with the AIDL.
490 for get_key_error in GetKeyErrorCode::enum_values() {
491 let (tx, rx) = oneshot::channel();
492 let cb = GetKeyCallback::new_native_binder(tx);
493 assert!(cb.onError(get_key_error, "error").is_ok());
494
495 let result = tokio_rt().block_on(rx).unwrap();
496 assert_eq!(
497 result.unwrap_err().downcast::<Error>().unwrap(),
498 Error::Rc(error_mapping[&get_key_error]),
499 );
500 }
Tri Voe8f04442022-12-21 08:53:56 -0800501 }
502
503 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800504 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800505 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800506 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800507 assert!(cb.onSuccess().is_ok());
508
Tri Vo437d0142023-01-18 16:43:49 -0800509 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800510 }
511
512 #[test]
513 fn test_store_upgraded_key_cb_error() {
514 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800515 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800516 assert!(cb.onError("oh no! it failed").is_ok());
517
Tri Vo437d0142023-01-18 16:43:49 -0800518 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800519 assert_eq!(
520 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800521 Error::Rc(ResponseCode::SYSTEM_ERROR)
522 );
523 }
524
525 #[test]
526 fn test_get_mock_key_success() {
527 let mock_key =
528 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
529 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
530
531 let key = tokio_rt()
532 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
533 .unwrap();
534 assert_eq!(key, mock_key);
535 }
536
537 #[test]
538 fn test_get_mock_key_timeout() {
539 let mock_key =
540 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800541 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800542 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
543
544 let result =
545 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
546 assert_eq!(
547 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800548 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800549 );
550 }
551
552 #[test]
553 fn test_store_mock_key_success() {
554 let mock_key =
555 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
556 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
557 tokio_rt()
558 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
559 .unwrap();
560 }
561
562 #[test]
563 fn test_store_mock_key_timeout() {
564 let mock_key =
565 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800566 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800567 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
568
569 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
570 &registration,
571 &[],
572 &[],
573 ));
574 assert_eq!(
575 result.unwrap_err().downcast::<Error>().unwrap(),
576 Error::Rc(ResponseCode::SYSTEM_ERROR)
Seth Moorea55428e2023-01-10 13:07:31 -0800577 );
578 }
579
580 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800581 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800582 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800583 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000584 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800585 assert!(!key.keyBlob.is_empty());
586 assert!(!key.encodedCertChain.is_empty());
587 }
588
589 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800590 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800591 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800592 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800593
594 // Multiple calls should return the same key.
Alice Wangbf6a6932023-11-07 11:47:12 +0000595 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
596 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800597
598 assert_eq!(first_key.keyBlob, second_key.keyBlob);
599 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
600 }
601
602 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800603 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800604 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800605 let first_key_id = get_next_key_id();
606 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800607
608 // Different callers should be getting different keys.
Alice Wangbf6a6932023-11-07 11:47:12 +0000609 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, first_key_id).unwrap();
610 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800611
612 assert_ne!(first_key.keyBlob, second_key.keyBlob);
613 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
614 }
615
616 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800617 // Couple of things to note:
618 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
619 // keystore.
620 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
621 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800622 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800623 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800624 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000625 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800626 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800627
Alice Wangbf6a6932023-11-07 11:47:12 +0000628 assert!(
629 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &key.keyBlob, &new_blob).is_ok()
630 );
Tri Vobac3b522023-01-23 13:10:24 -0800631
Alice Wangbf6a6932023-11-07 11:47:12 +0000632 let new_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800633
634 // Restore original key so that we don't leave RKPD with invalid blobs.
Alice Wangbf6a6932023-11-07 11:47:12 +0000635 assert!(
636 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &new_blob, &key.keyBlob).is_ok()
637 );
Tri Vobac3b522023-01-23 13:10:24 -0800638 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800639 }
Tri Vo30268da2023-01-24 15:35:45 -0800640
641 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800642 fn test_stress_get_rkpd_attestation_key() {
643 binder::ProcessState::start_thread_pool();
644 let key_id = get_next_key_id();
645 let mut threads = vec![];
646 const NTHREADS: u32 = 10;
647 const NCALLS: u32 = 1000;
648
649 for _ in 0..NTHREADS {
650 threads.push(std::thread::spawn(move || {
651 for _ in 0..NCALLS {
Alice Wangbf6a6932023-11-07 11:47:12 +0000652 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vo02f0fa42023-01-24 12:32:08 -0800653 assert!(!key.keyBlob.is_empty());
654 assert!(!key.encodedCertChain.is_empty());
655 }
656 }));
657 }
658
659 for t in threads {
660 assert!(t.join().is_ok());
661 }
662 }
Tri Voe8f04442022-12-21 08:53:56 -0800663}