blob: 5f92d82f31b2b1082236ef237db4bdf2bfae75cb [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 crate::ks_err;
Alice Wang83c6aef2023-11-03 17:17:34 +000019use crate::watchdog_helper::watchdog as wd;
Tri Voe8f04442022-12-21 08:53:56 -080020use android_security_rkp_aidl::aidl::android::security::rkp::{
Seth Moore484010a2023-01-31 11:22:26 -080021 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
22 IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
Tri Voe8f04442022-12-21 08:53:56 -080023 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
Seth Moorea55428e2023-01-10 13:07:31 -080024 IRemoteProvisioning::IRemoteProvisioning,
25 IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
26 IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
27 RemotelyProvisionedKey::RemotelyProvisionedKey,
Tri Voe8f04442022-12-21 08:53:56 -080028};
29use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
30use anyhow::{Context, Result};
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))
Seth Moore613a1fd2023-01-11 10:42:26 -080094 .context(ks_err!("GetRegistrationCallback cancelled.")),
95 );
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}'");
Seth Moore613a1fd2023-01-11 10:42:26 -0800101 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800102 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
103 .context(ks_err!("GetRegistrationCallback failed: {:?}", description)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800104 );
105 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"))
113 .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
114
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)
Tri Voe8f04442022-12-21 08:53:56 -0800120 .context(ks_err!("Trying to get registration."))?;
121
Tri Vo437d0142023-01-18 16:43:49 -0800122 match timeout(RKPD_TIMEOUT, rx).await {
123 Err(e) => {
124 Err(Error::Rc(ResponseCode::SYSTEM_ERROR)).context(ks_err!("Waiting for RKPD: {:?}", e))
125 }
126 Ok(v) => v.unwrap(),
127 }
Tri Voe8f04442022-12-21 08:53:56 -0800128}
129
Tri Voe8f04442022-12-21 08:53:56 -0800130struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800131 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800132}
133
134impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800135 pub fn new_native_binder(
136 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800137 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800138 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800139 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800140 }
141}
142
143impl Interface for GetKeyCallback {}
144
145impl IGetKeyCallback for GetKeyCallback {
146 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
147 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800148 self.key_tx.send(Ok(RemotelyProvisionedKey {
149 keyBlob: key.keyBlob.clone(),
150 encodedCertChain: key.encodedCertChain.clone(),
151 }));
152 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800153 }
154 fn onCancel(&self) -> binder::Result<()> {
155 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800156 log::warn!("IGetKeyCallback cancelled");
157 self.key_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800158 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
159 .context(ks_err!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800160 );
161 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800162 }
Seth Moore484010a2023-01-31 11:22:26 -0800163 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800164 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800165 log::error!("IGetKeyCallback failed: {description}");
166 let rc = match error {
167 GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
168 GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
169 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
170 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
171 }
172 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
173 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
174 }
175 _ => {
176 log::error!("Unexpected error from rkpd: {error:?}");
177 ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
178 }
179 };
180 self.key_tx.send(Err(Error::Rc(rc)).context(ks_err!(
181 "GetKeyCallback failed: {:?} {:?}",
182 error,
183 description
184 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800185 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800186 }
187}
188
Tri Vo437d0142023-01-18 16:43:49 -0800189async fn get_rkpd_attestation_key_from_registration_async(
190 registration: &Strong<dyn IRegistration>,
191 caller_uid: u32,
192) -> Result<RemotelyProvisionedKey> {
193 let (tx, rx) = oneshot::channel();
194 let cb = GetKeyCallback::new_native_binder(tx);
195
196 registration
197 .getKey(caller_uid.try_into().unwrap(), &cb)
198 .context(ks_err!("Trying to get key."))?;
199
200 match timeout(RKPD_TIMEOUT, rx).await {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800201 Err(e) => {
202 // Make a best effort attempt to cancel the timed out request.
203 if let Err(e) = registration.cancelGetKey(&cb) {
204 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
205 }
206 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
207 .context(ks_err!("Waiting for RKPD key timed out: {:?}", e))
208 }
Tri Vo437d0142023-01-18 16:43:49 -0800209 Ok(v) => v.unwrap(),
210 }
211}
212
Tri Voe8f04442022-12-21 08:53:56 -0800213async fn get_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000214 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800215 caller_uid: u32,
216) -> Result<RemotelyProvisionedKey> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000217 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800218 .await
219 .context(ks_err!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800220 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800221}
222
Seth Moorea55428e2023-01-10 13:07:31 -0800223struct StoreUpgradedKeyCallback {
224 completer: SafeSender<Result<()>>,
225}
226
227impl StoreUpgradedKeyCallback {
228 pub fn new_native_binder(
229 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800230 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800231 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800232 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800233 }
234}
235
236impl Interface for StoreUpgradedKeyCallback {}
237
238impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
239 fn onSuccess(&self) -> binder::Result<()> {
240 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800241 self.completer.send(Ok(()));
242 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800243 }
244
245 fn onError(&self, error: &str) -> binder::Result<()> {
246 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800247 log::error!("IGetRegistrationCallback failed: {error}");
248 self.completer.send(
Tri Vo437d0142023-01-18 16:43:49 -0800249 Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Seth Moore613a1fd2023-01-11 10:42:26 -0800250 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
251 );
252 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800253 }
254}
255
Tri Vo437d0142023-01-18 16:43:49 -0800256async fn store_rkpd_attestation_key_with_registration_async(
257 registration: &Strong<dyn IRegistration>,
258 key_blob: &[u8],
259 upgraded_blob: &[u8],
260) -> Result<()> {
261 let (tx, rx) = oneshot::channel();
262 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
263
264 registration
265 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
266 .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
267
268 match timeout(RKPD_TIMEOUT, rx).await {
269 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
270 .context(ks_err!("Waiting for RKPD to complete storing key: {:?}", e)),
271 Ok(v) => v.unwrap(),
272 }
273}
274
Tri Voe8f04442022-12-21 08:53:56 -0800275async fn store_rkpd_attestation_key_async(
Alice Wangbf6a6932023-11-07 11:47:12 +0000276 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800277 key_blob: &[u8],
278 upgraded_blob: &[u8],
279) -> Result<()> {
Alice Wangbf6a6932023-11-07 11:47:12 +0000280 let registration = get_rkpd_registration(rpc_name)
Tri Voe8f04442022-12-21 08:53:56 -0800281 .await
282 .context(ks_err!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800283 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800284}
285
286/// Get attestation key from RKPD.
Alice Wangbf6a6932023-11-07 11:47:12 +0000287pub fn get_rkpd_attestation_key(rpc_name: &str, caller_uid: u32) -> Result<RemotelyProvisionedKey> {
Tri Voe8f04442022-12-21 08:53:56 -0800288 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
Alice Wangbf6a6932023-11-07 11:47:12 +0000289 tokio_rt().block_on(get_rkpd_attestation_key_async(rpc_name, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800290}
291
292/// Store attestation key in RKPD.
293pub fn store_rkpd_attestation_key(
Alice Wangbf6a6932023-11-07 11:47:12 +0000294 rpc_name: &str,
Tri Voe8f04442022-12-21 08:53:56 -0800295 key_blob: &[u8],
296 upgraded_blob: &[u8],
297) -> Result<()> {
298 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
Alice Wangbf6a6932023-11-07 11:47:12 +0000299 tokio_rt().block_on(store_rkpd_attestation_key_async(rpc_name, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800300}
301
302#[cfg(test)]
303mod tests {
304 use super::*;
305 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Seth Moore484010a2023-01-31 11:22:26 -0800306 use std::collections::HashMap;
Tri Vo4b1cd822023-01-23 13:05:35 -0800307 use std::sync::atomic::{AtomicU32, Ordering};
Tri Vo215f12e2023-02-15 16:23:39 -0800308 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800309
Alice Wangbf6a6932023-11-07 11:47:12 +0000310 const DEFAULT_RPC_SERVICE_NAME: &str =
311 "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
312
Tri Vo215f12e2023-02-15 16:23:39 -0800313 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800314 key: RemotelyProvisionedKey,
315 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800316 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800317 }
318
Tri Vo215f12e2023-02-15 16:23:39 -0800319 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
320
Tri Voe8f04442022-12-21 08:53:56 -0800321 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800322 pub fn new_native_binder(
323 key: &RemotelyProvisionedKey,
324 latency: Option<Duration>,
325 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800326 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800327 key: RemotelyProvisionedKey {
328 keyBlob: key.keyBlob.clone(),
329 encodedCertChain: key.encodedCertChain.clone(),
330 },
331 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800332 thread_join_handles: Vec::new(),
333 })));
Tri Voe8f04442022-12-21 08:53:56 -0800334 BnRegistration::new_binder(result, BinderFeatures::default())
335 }
336 }
337
Tri Vo215f12e2023-02-15 16:23:39 -0800338 impl Drop for MockRegistration {
339 fn drop(&mut self) {
340 let mut values = self.0.lock().unwrap();
341 for handle in values.thread_join_handles.iter_mut() {
342 // These are test threads. So, no need to worry too much about error handling.
343 handle.take().unwrap().join().unwrap();
344 }
345 }
346 }
347
Tri Voe8f04442022-12-21 08:53:56 -0800348 impl Interface for MockRegistration {}
349
350 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800351 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800352 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800353 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800354 keyBlob: values.key.keyBlob.clone(),
355 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800356 };
Tri Vo215f12e2023-02-15 16:23:39 -0800357 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800358 let get_key_cb = cb.clone();
359
360 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800361 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800362 if let Some(duration) = latency {
363 std::thread::sleep(duration);
364 }
365 get_key_cb.onSuccess(&key).unwrap();
366 });
Tri Vo215f12e2023-02-15 16:23:39 -0800367 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800368 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800369 }
370
371 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800372 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800373 }
374
Seth Moorea55428e2023-01-10 13:07:31 -0800375 fn storeUpgradedKeyAsync(
376 &self,
377 _: &[u8],
378 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800379 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800380 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800381 // We are primarily concerned with timing out correctly. Storing the key in this mock
382 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800383 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800384 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800385 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800386
387 std::thread::spawn(move || {
388 if let Some(duration) = latency {
389 std::thread::sleep(duration);
390 }
391 store_cb.onSuccess().unwrap();
392 });
393 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800394 }
395 }
396
Tri Vo437d0142023-01-18 16:43:49 -0800397 fn get_mock_registration(
398 key: &RemotelyProvisionedKey,
399 latency: Option<Duration>,
400 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800401 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800402 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800403 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800404
405 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800406 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800407 }
408
Tri Vo4b1cd822023-01-23 13:05:35 -0800409 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
410 // different test cases.
411 fn get_next_key_id() -> u32 {
412 static ID: AtomicU32 = AtomicU32::new(0);
413 ID.fetch_add(1, Ordering::Relaxed)
414 }
415
Tri Voe8f04442022-12-21 08:53:56 -0800416 #[test]
417 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800418 let key: RemotelyProvisionedKey = Default::default();
419 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800420 assert!(registration.is_ok());
421 }
422
423 #[test]
424 fn test_get_registration_cb_cancel() {
425 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800426 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800427 assert!(cb.onCancel().is_ok());
428
Tri Vo437d0142023-01-18 16:43:49 -0800429 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800430 assert_eq!(
431 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800432 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800433 );
434 }
435
436 #[test]
437 fn test_get_registration_cb_error() {
438 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800439 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800440 assert!(cb.onError("error").is_ok());
441
Tri Vo437d0142023-01-18 16:43:49 -0800442 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800443 assert_eq!(
444 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800445 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800446 );
447 }
448
449 #[test]
450 fn test_get_key_cb_success() {
451 let mock_key =
452 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
453 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800454 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800455 assert!(cb.onSuccess(&mock_key).is_ok());
456
Tri Vo437d0142023-01-18 16:43:49 -0800457 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800458 assert_eq!(key, mock_key);
459 }
460
461 #[test]
462 fn test_get_key_cb_cancel() {
463 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800464 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800465 assert!(cb.onCancel().is_ok());
466
Tri Vo437d0142023-01-18 16:43:49 -0800467 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800468 assert_eq!(
469 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800470 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800471 );
472 }
473
474 #[test]
475 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800476 let error_mapping = HashMap::from([
477 (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
478 (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
479 (
480 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
481 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
482 ),
483 (
484 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
485 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
486 ),
487 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800488
Seth Moore484010a2023-01-31 11:22:26 -0800489 // Loop over the generated list of enum values to better ensure this test stays in
490 // sync with the AIDL.
491 for get_key_error in GetKeyErrorCode::enum_values() {
492 let (tx, rx) = oneshot::channel();
493 let cb = GetKeyCallback::new_native_binder(tx);
494 assert!(cb.onError(get_key_error, "error").is_ok());
495
496 let result = tokio_rt().block_on(rx).unwrap();
497 assert_eq!(
498 result.unwrap_err().downcast::<Error>().unwrap(),
499 Error::Rc(error_mapping[&get_key_error]),
500 );
501 }
Tri Voe8f04442022-12-21 08:53:56 -0800502 }
503
504 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800505 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800506 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800507 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800508 assert!(cb.onSuccess().is_ok());
509
Tri Vo437d0142023-01-18 16:43:49 -0800510 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800511 }
512
513 #[test]
514 fn test_store_upgraded_key_cb_error() {
515 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800516 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800517 assert!(cb.onError("oh no! it failed").is_ok());
518
Tri Vo437d0142023-01-18 16:43:49 -0800519 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800520 assert_eq!(
521 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800522 Error::Rc(ResponseCode::SYSTEM_ERROR)
523 );
524 }
525
526 #[test]
527 fn test_get_mock_key_success() {
528 let mock_key =
529 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
530 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
531
532 let key = tokio_rt()
533 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
534 .unwrap();
535 assert_eq!(key, mock_key);
536 }
537
538 #[test]
539 fn test_get_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 =
546 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
547 assert_eq!(
548 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800549 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800550 );
551 }
552
553 #[test]
554 fn test_store_mock_key_success() {
555 let mock_key =
556 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
557 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
558 tokio_rt()
559 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
560 .unwrap();
561 }
562
563 #[test]
564 fn test_store_mock_key_timeout() {
565 let mock_key =
566 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800567 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800568 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
569
570 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
571 &registration,
572 &[],
573 &[],
574 ));
575 assert_eq!(
576 result.unwrap_err().downcast::<Error>().unwrap(),
577 Error::Rc(ResponseCode::SYSTEM_ERROR)
Seth Moorea55428e2023-01-10 13:07:31 -0800578 );
579 }
580
581 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800582 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800583 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800584 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000585 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800586 assert!(!key.keyBlob.is_empty());
587 assert!(!key.encodedCertChain.is_empty());
588 }
589
590 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800591 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800592 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800593 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800594
595 // Multiple calls should return the same key.
Alice Wangbf6a6932023-11-07 11:47:12 +0000596 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
597 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800598
599 assert_eq!(first_key.keyBlob, second_key.keyBlob);
600 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
601 }
602
603 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800604 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800605 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800606 let first_key_id = get_next_key_id();
607 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800608
609 // Different callers should be getting different keys.
Alice Wangbf6a6932023-11-07 11:47:12 +0000610 let first_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, first_key_id).unwrap();
611 let second_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800612
613 assert_ne!(first_key.keyBlob, second_key.keyBlob);
614 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
615 }
616
617 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800618 // Couple of things to note:
619 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
620 // keystore.
621 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
622 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800623 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800624 binder::ProcessState::start_thread_pool();
Tri Vo4b1cd822023-01-23 13:05:35 -0800625 let key_id = get_next_key_id();
Alice Wangbf6a6932023-11-07 11:47:12 +0000626 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800627 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800628
Alice Wangbf6a6932023-11-07 11:47:12 +0000629 assert!(
630 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &key.keyBlob, &new_blob).is_ok()
631 );
Tri Vobac3b522023-01-23 13:10:24 -0800632
Alice Wangbf6a6932023-11-07 11:47:12 +0000633 let new_key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800634
635 // Restore original key so that we don't leave RKPD with invalid blobs.
Alice Wangbf6a6932023-11-07 11:47:12 +0000636 assert!(
637 store_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, &new_blob, &key.keyBlob).is_ok()
638 );
Tri Vobac3b522023-01-23 13:10:24 -0800639 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800640 }
Tri Vo30268da2023-01-24 15:35:45 -0800641
642 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800643 fn test_stress_get_rkpd_attestation_key() {
644 binder::ProcessState::start_thread_pool();
645 let key_id = get_next_key_id();
646 let mut threads = vec![];
647 const NTHREADS: u32 = 10;
648 const NCALLS: u32 = 1000;
649
650 for _ in 0..NTHREADS {
651 threads.push(std::thread::spawn(move || {
652 for _ in 0..NCALLS {
Alice Wangbf6a6932023-11-07 11:47:12 +0000653 let key = get_rkpd_attestation_key(DEFAULT_RPC_SERVICE_NAME, key_id).unwrap();
Tri Vo02f0fa42023-01-24 12:32:08 -0800654 assert!(!key.keyBlob.is_empty());
655 assert!(!key.encodedCertChain.is_empty());
656 }
657 }));
658 }
659
660 for t in threads {
661 assert!(t.join().is_ok());
662 }
663 }
Tri Voe8f04442022-12-21 08:53:56 -0800664}