blob: 40c06e5c65a6d6a5c48d40de903c99a22547c2e0 [file] [log] [blame]
Max Bires148c08e2020-10-13 13:41:41 -07001// Copyright 2020, 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//! This is the implementation for the remote provisioning AIDL interface between
16//! the network providers for remote provisioning and the system. This interface
17//! allows the caller to prompt the Remote Provisioning HAL to generate keys and
18//! CBOR blobs that can be ferried to a provisioning server that will return
19//! certificate chains signed by some root authority and stored in a keystore SQLite
20//! DB.
21
Max Biresb2e1d032021-02-08 21:35:05 -080022use std::collections::HashMap;
Max Bires148c08e2020-10-13 13:41:41 -070023
Max Biresb2e1d032021-02-08 21:35:05 -080024use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Max Bires97f96812021-02-23 23:44:57 -080025 Algorithm::Algorithm, AttestationKey::AttestationKey, Certificate::Certificate,
Max Bires834dd362021-03-23 13:01:57 -070026 DeviceInfo::DeviceInfo, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
27 KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
28 MacedPublicKey::MacedPublicKey, ProtectedData::ProtectedData, SecurityLevel::SecurityLevel,
29 Tag::Tag,
Max Biresb2e1d032021-02-08 21:35:05 -080030};
Max Bires148c08e2020-10-13 13:41:41 -070031use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
32 AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
Max Biresd2ce46b2021-07-06 02:54:47 -070033 IRemoteProvisioning::IRemoteProvisioning, ImplInfo::ImplInfo,
Max Bires148c08e2020-10-13 13:41:41 -070034};
Andrew Walbrande45c8b2021-04-13 14:42:38 +000035use android_security_remoteprovisioning::binder::{BinderFeatures, Strong};
Max Bires97f96812021-02-23 23:44:57 -080036use android_system_keystore2::aidl::android::system::keystore2::{
37 Domain::Domain, KeyDescriptor::KeyDescriptor,
38};
Max Biresb2e1d032021-02-08 21:35:05 -080039use anyhow::{Context, Result};
Max Bires97f96812021-02-23 23:44:57 -080040use keystore2_crypto::parse_subject_from_certificate;
41use std::sync::atomic::{AtomicBool, Ordering};
Max Bires148c08e2020-10-13 13:41:41 -070042
Max Bires97f96812021-02-23 23:44:57 -080043use crate::database::{CertificateChain, KeystoreDB, Uuid};
44use crate::error::{self, map_or_log_err, map_rem_prov_error, Error};
Max Biresb2e1d032021-02-08 21:35:05 -080045use crate::globals::{get_keymint_device, get_remotely_provisioned_component, DB};
Janis Danisevskis5f3a0572021-06-18 11:26:42 -070046use crate::utils::watchdog as wd;
Max Bires148c08e2020-10-13 13:41:41 -070047
Max Bires97f96812021-02-23 23:44:57 -080048/// Contains helper functions to check if remote provisioning is enabled on the system and, if so,
49/// to assign and retrieve attestation keys and certificate chains.
50#[derive(Default)]
51pub struct RemProvState {
52 security_level: SecurityLevel,
53 km_uuid: Uuid,
54 is_hal_present: AtomicBool,
55}
56
57impl RemProvState {
58 /// Creates a RemProvState struct.
59 pub fn new(security_level: SecurityLevel, km_uuid: Uuid) -> Self {
60 Self { security_level, km_uuid, is_hal_present: AtomicBool::new(true) }
61 }
62
63 /// Checks if remote provisioning is enabled and partially caches the result. On a hybrid system
64 /// remote provisioning can flip from being disabled to enabled depending on responses from the
65 /// server, so unfortunately caching the presence or absence of the HAL is not enough to fully
66 /// make decisions about the state of remote provisioning during runtime.
67 fn check_rem_prov_enabled(&self, db: &mut KeystoreDB) -> Result<bool> {
68 if !self.is_hal_present.load(Ordering::Relaxed)
69 || get_remotely_provisioned_component(&self.security_level).is_err()
70 {
71 self.is_hal_present.store(false, Ordering::Relaxed);
72 return Ok(false);
73 }
74 // To check if remote provisioning is enabled on a system that supports both remote
75 // provisioning and factory provisioned keys, we only need to check if there are any
76 // keys at all generated to indicate if the app has gotten the signal to begin filling
77 // the key pool from the server.
78 let pool_status = db
79 .get_attestation_pool_status(0 /* date */, &self.km_uuid)
80 .context("In check_rem_prov_enabled: failed to get attestation pool status.")?;
81 Ok(pool_status.total != 0)
82 }
83
84 /// Fetches a remote provisioning attestation key and certificate chain inside of the
85 /// returned `CertificateChain` struct if one exists for the given caller_uid. If one has not
86 /// been assigned, this function will assign it. If there are no signed attestation keys
87 /// available to be assigned, it will return the ResponseCode `OUT_OF_KEYS`
88 fn get_rem_prov_attest_key(
89 &self,
90 key: &KeyDescriptor,
91 caller_uid: u32,
92 db: &mut KeystoreDB,
93 ) -> Result<Option<CertificateChain>> {
94 match key.domain {
95 Domain::APP => {
96 // Attempt to get an Attestation Key once. If it fails, then the app doesn't
97 // have a valid chain assigned to it. The helper function will return None after
98 // attempting to assign a key. An error will be thrown if the pool is simply out
99 // of usable keys. Then another attempt to fetch the just-assigned key will be
100 // made. If this fails too, something is very wrong.
101 self.get_rem_prov_attest_key_helper(key, caller_uid, db)
102 .context("In get_rem_prov_attest_key: Failed to get a key")?
103 .map_or_else(
104 || self.get_rem_prov_attest_key_helper(key, caller_uid, db),
105 |v| Ok(Some(v)),
106 )
107 .context(concat!(
108 "In get_rem_prov_attest_key: Failed to get a key after",
109 "attempting to assign one."
110 ))?
111 .map_or_else(
112 || {
113 Err(Error::sys()).context(concat!(
114 "In get_rem_prov_attest_key: Attempted to assign a ",
115 "key and failed silently. Something is very wrong."
116 ))
117 },
118 |cert_chain| Ok(Some(cert_chain)),
119 )
120 }
121 _ => Ok(None),
122 }
123 }
124
125 /// Returns None if an AttestationKey fails to be assigned. Errors if no keys are available.
126 fn get_rem_prov_attest_key_helper(
127 &self,
128 key: &KeyDescriptor,
129 caller_uid: u32,
130 db: &mut KeystoreDB,
131 ) -> Result<Option<CertificateChain>> {
132 let cert_chain = db
133 .retrieve_attestation_key_and_cert_chain(key.domain, caller_uid as i64, &self.km_uuid)
134 .context("In get_rem_prov_attest_key_helper: Failed to retrieve a key + cert chain")?;
135 match cert_chain {
136 Some(cert_chain) => Ok(Some(cert_chain)),
137 // Either this app needs to be assigned a key, or the pool is empty. An error will
138 // be thrown if there is no key available to assign. This will indicate that the app
139 // should be nudged to provision more keys so keystore can retry.
140 None => {
141 db.assign_attestation_key(key.domain, caller_uid as i64, &self.km_uuid)
142 .context("In get_rem_prov_attest_key_helper: Failed to assign a key")?;
143 Ok(None)
144 }
145 }
146 }
147
148 fn is_asymmetric_key(&self, params: &[KeyParameter]) -> bool {
149 params.iter().any(|kp| {
150 matches!(
151 kp,
152 KeyParameter {
153 tag: Tag::ALGORITHM,
154 value: KeyParameterValue::Algorithm(Algorithm::RSA)
155 } | KeyParameter {
156 tag: Tag::ALGORITHM,
157 value: KeyParameterValue::Algorithm(Algorithm::EC)
158 }
159 )
160 })
161 }
162
163 /// Checks to see (1) if the key in question should be attested to based on the algorithm and
164 /// (2) if remote provisioning is present and enabled on the system. If these conditions are
165 /// met, it makes an attempt to fetch the attestation key assigned to the `caller_uid`.
166 ///
167 /// It returns the ResponseCode `OUT_OF_KEYS` if there is not one key currently assigned to the
168 /// `caller_uid` and there are none available to assign.
Janis Danisevskis3541f3e2021-03-20 14:18:52 -0700169 pub fn get_remotely_provisioned_attestation_key_and_certs(
Max Bires97f96812021-02-23 23:44:57 -0800170 &self,
171 key: &KeyDescriptor,
172 caller_uid: u32,
173 params: &[KeyParameter],
174 db: &mut KeystoreDB,
Janis Danisevskis3541f3e2021-03-20 14:18:52 -0700175 ) -> Result<Option<(AttestationKey, Certificate)>> {
Max Bires97f96812021-02-23 23:44:57 -0800176 if !self.is_asymmetric_key(params) || !self.check_rem_prov_enabled(db)? {
177 // There is no remote provisioning component for this security level on the
178 // device. Return None so the underlying KM instance knows to use its
179 // factory provisioned key instead. Alternatively, it's not an asymmetric key
180 // and therefore will not be attested.
Janis Danisevskis3541f3e2021-03-20 14:18:52 -0700181 Ok(None)
Max Bires97f96812021-02-23 23:44:57 -0800182 } else {
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700183 match self.get_rem_prov_attest_key(key, caller_uid, db) {
Max Bires31cdfb82021-07-06 02:59:25 -0700184 Err(e) => {
185 log::error!(
186 concat!(
187 "In get_remote_provisioning_key_and_certs: Failed to get ",
188 "attestation key. {:?}"
189 ),
190 e
191 );
192 Ok(None)
193 }
194 Ok(v) => match v {
195 Some(cert_chain) => Ok(Some((
196 AttestationKey {
197 keyBlob: cert_chain.private_key.to_vec(),
198 attestKeyParams: vec![],
199 issuerSubjectName: parse_subject_from_certificate(
200 &cert_chain.batch_cert,
201 )
Max Bires97f96812021-02-23 23:44:57 -0800202 .context(concat!(
Max Bires31cdfb82021-07-06 02:59:25 -0700203 "In get_remote_provisioning_key_and_certs: Failed to ",
204 "parse subject."
205 ))?,
206 },
207 Certificate { encodedCertificate: cert_chain.cert_chain },
208 ))),
209 None => Ok(None),
210 },
Max Bires97f96812021-02-23 23:44:57 -0800211 }
212 }
213 }
214}
Max Bires148c08e2020-10-13 13:41:41 -0700215/// Implementation of the IRemoteProvisioning service.
Max Biresb2e1d032021-02-08 21:35:05 -0800216#[derive(Default)]
Max Bires148c08e2020-10-13 13:41:41 -0700217pub struct RemoteProvisioningService {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700218 device_by_sec_level: HashMap<SecurityLevel, Strong<dyn IRemotelyProvisionedComponent>>,
Max Biresd2ce46b2021-07-06 02:54:47 -0700219 curve_by_sec_level: HashMap<SecurityLevel, i32>,
Max Bires148c08e2020-10-13 13:41:41 -0700220}
221
222impl RemoteProvisioningService {
Max Biresb2e1d032021-02-08 21:35:05 -0800223 fn get_dev_by_sec_level(
224 &self,
225 sec_level: &SecurityLevel,
226 ) -> Result<Strong<dyn IRemotelyProvisionedComponent>> {
227 if let Some(dev) = self.device_by_sec_level.get(sec_level) {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700228 Ok(dev.clone())
Max Biresb2e1d032021-02-08 21:35:05 -0800229 } else {
230 Err(error::Error::sys()).context(concat!(
231 "In get_dev_by_sec_level: Remote instance for requested security level",
232 " not found."
233 ))
234 }
235 }
236
Max Bires148c08e2020-10-13 13:41:41 -0700237 /// Creates a new instance of the remote provisioning service
Stephen Crane221bbb52020-12-16 15:52:10 -0800238 pub fn new_native_binder() -> Result<Strong<dyn IRemoteProvisioning>> {
Max Biresb2e1d032021-02-08 21:35:05 -0800239 let mut result: Self = Default::default();
240 let dev = get_remotely_provisioned_component(&SecurityLevel::TRUSTED_ENVIRONMENT)
241 .context("In new_native_binder: Failed to get TEE Remote Provisioner instance.")?;
Max Biresd2ce46b2021-07-06 02:54:47 -0700242 result.curve_by_sec_level.insert(
243 SecurityLevel::TRUSTED_ENVIRONMENT,
244 dev.getHardwareInfo()
245 .context("In new_native_binder: Failed to get hardware info for the TEE.")?
246 .supportedEekCurve,
247 );
Max Biresb2e1d032021-02-08 21:35:05 -0800248 result.device_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, dev);
249 if let Ok(dev) = get_remotely_provisioned_component(&SecurityLevel::STRONGBOX) {
Max Biresd2ce46b2021-07-06 02:54:47 -0700250 result.curve_by_sec_level.insert(
251 SecurityLevel::STRONGBOX,
252 dev.getHardwareInfo()
253 .context("In new_native_binder: Failed to get hardware info for StrongBox.")?
254 .supportedEekCurve,
255 );
Max Biresb2e1d032021-02-08 21:35:05 -0800256 result.device_by_sec_level.insert(SecurityLevel::STRONGBOX, dev);
257 }
Andrew Walbrande45c8b2021-04-13 14:42:38 +0000258 Ok(BnRemoteProvisioning::new_binder(result, BinderFeatures::default()))
Max Bires148c08e2020-10-13 13:41:41 -0700259 }
260
Max Bires148c08e2020-10-13 13:41:41 -0700261 /// Generates a CBOR blob which will be assembled by the calling code into a larger
262 /// CBOR blob intended for delivery to a provisioning serever. This blob will contain
263 /// `num_csr` certificate signing requests for attestation keys generated in the TEE,
264 /// along with a server provided `eek` and `challenge`. The endpoint encryption key will
265 /// be used to encrypt the sensitive contents being transmitted to the server, and the
266 /// challenge will ensure freshness. A `test_mode` flag will instruct the remote provisioning
267 /// HAL if it is okay to accept EEKs that aren't signed by something that chains back to the
268 /// baked in root of trust in the underlying IRemotelyProvisionedComponent instance.
Max Bires834dd362021-03-23 13:01:57 -0700269 #[allow(clippy::too_many_arguments)]
Max Bires148c08e2020-10-13 13:41:41 -0700270 pub fn generate_csr(
271 &self,
Max Biresb2e1d032021-02-08 21:35:05 -0800272 test_mode: bool,
273 num_csr: i32,
274 eek: &[u8],
275 challenge: &[u8],
276 sec_level: SecurityLevel,
277 protected_data: &mut ProtectedData,
Max Bires834dd362021-03-23 13:01:57 -0700278 device_info: &mut DeviceInfo,
Max Bires148c08e2020-10-13 13:41:41 -0700279 ) -> Result<Vec<u8>> {
Max Biresb2e1d032021-02-08 21:35:05 -0800280 let dev = self.get_dev_by_sec_level(&sec_level)?;
281 let (_, _, uuid) = get_keymint_device(&sec_level)?;
282 let keys_to_sign = DB.with::<_, Result<Vec<MacedPublicKey>>>(|db| {
283 let mut db = db.borrow_mut();
284 Ok(db
285 .fetch_unsigned_attestation_keys(num_csr, &uuid)?
286 .iter()
287 .map(|key| MacedPublicKey { macedKey: key.to_vec() })
288 .collect())
289 })?;
Max Bires834dd362021-03-23 13:01:57 -0700290 let mut mac = map_rem_prov_error(dev.generateCertificateRequest(
Max Biresb2e1d032021-02-08 21:35:05 -0800291 test_mode,
292 &keys_to_sign,
293 eek,
294 challenge,
Max Bires834dd362021-03-23 13:01:57 -0700295 device_info,
Max Biresb2e1d032021-02-08 21:35:05 -0800296 protected_data,
297 ))
298 .context("In generate_csr: Failed to generate csr")?;
Max Bires97f96812021-02-23 23:44:57 -0800299 // TODO(b/180392379): Replace this manual CBOR generation with the cbor-serde crate as well.
300 // This generates an array consisting of the mac and the public key Maps.
301 // Just generate the actual MacedPublicKeys structure when the crate is
302 // available.
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700303 let mut cose_mac_0: Vec<u8> = vec![
304 (0b100_00000 | (keys_to_sign.len() + 1)) as u8,
305 0b010_11000, // mac
306 (mac.len() as u8),
307 ];
Max Bires97f96812021-02-23 23:44:57 -0800308 cose_mac_0.append(&mut mac);
Max Bires67e95122021-06-21 00:20:23 -0700309 // If this is a test mode key, there is an extra 6 bytes added as an additional entry in
310 // the COSE_Key struct to denote that.
311 let test_mode_entry_shift = if test_mode { 0 } else { 6 };
312 let byte_dist_mac0_payload = 8;
313 let cose_key_size = 83 - test_mode_entry_shift;
Max Bires97f96812021-02-23 23:44:57 -0800314 for maced_public_key in keys_to_sign {
Max Bires67e95122021-06-21 00:20:23 -0700315 if maced_public_key.macedKey.len() > cose_key_size + byte_dist_mac0_payload {
316 cose_mac_0.extend_from_slice(
317 &maced_public_key.macedKey
318 [byte_dist_mac0_payload..cose_key_size + byte_dist_mac0_payload],
319 );
Max Bires97f96812021-02-23 23:44:57 -0800320 }
321 }
322 Ok(cose_mac_0)
Max Bires148c08e2020-10-13 13:41:41 -0700323 }
324
325 /// Provisions a certificate chain for a key whose CSR was included in generate_csr. The
326 /// `public_key` is used to index into the SQL database in order to insert the `certs` blob
327 /// which represents a PEM encoded X.509 certificate chain. The `expiration_date` is provided
328 /// as a convenience from the caller to avoid having to parse the certificates semantically
329 /// here.
330 pub fn provision_cert_chain(
331 &self,
332 public_key: &[u8],
Max Biresb2e1d032021-02-08 21:35:05 -0800333 batch_cert: &[u8],
Max Bires148c08e2020-10-13 13:41:41 -0700334 certs: &[u8],
335 expiration_date: i64,
336 sec_level: SecurityLevel,
337 ) -> Result<()> {
338 DB.with::<_, Result<()>>(|db| {
339 let mut db = db.borrow_mut();
340 let (_, _, uuid) = get_keymint_device(&sec_level)?;
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700341 db.store_signed_attestation_certificate_chain(
Max Bires148c08e2020-10-13 13:41:41 -0700342 public_key,
Max Biresb2e1d032021-02-08 21:35:05 -0800343 batch_cert,
Max Bires148c08e2020-10-13 13:41:41 -0700344 certs, /* DER encoded certificate chain */
345 expiration_date,
346 &uuid,
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700347 )
Max Bires148c08e2020-10-13 13:41:41 -0700348 })
349 }
350
351 /// Submits a request to the Remote Provisioner HAL to generate a signing key pair.
352 /// `is_test_mode` indicates whether or not the returned public key should be marked as being
353 /// for testing in order to differentiate them from private keys. If the call is successful,
354 /// the key pair is then added to the database.
Max Biresb2e1d032021-02-08 21:35:05 -0800355 pub fn generate_key_pair(&self, is_test_mode: bool, sec_level: SecurityLevel) -> Result<()> {
356 let (_, _, uuid) = get_keymint_device(&sec_level)?;
357 let dev = self.get_dev_by_sec_level(&sec_level)?;
358 let mut maced_key = MacedPublicKey { macedKey: Vec::new() };
359 let priv_key =
360 map_rem_prov_error(dev.generateEcdsaP256KeyPair(is_test_mode, &mut maced_key))
361 .context("In generate_key_pair: Failed to generated ECDSA keypair.")?;
362 // TODO(b/180392379): This is a brittle hack that relies on the consistent formatting of
363 // the returned CBOR blob in order to extract the public key.
364 let data = &maced_key.macedKey;
365 if data.len() < 85 {
366 return Err(error::Error::sys()).context(concat!(
367 "In generate_key_pair: CBOR blob returned from",
368 "RemotelyProvisionedComponent is definitely malformatted or empty."
369 ));
370 }
371 let mut raw_key: Vec<u8> = vec![0; 64];
372 raw_key[0..32].clone_from_slice(&data[18..18 + 32]);
373 raw_key[32..64].clone_from_slice(&data[53..53 + 32]);
374 DB.with::<_, Result<()>>(|db| {
375 let mut db = db.borrow_mut();
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700376 db.create_attestation_key_entry(&maced_key.macedKey, &raw_key, &priv_key, &uuid)
Max Biresb2e1d032021-02-08 21:35:05 -0800377 })
378 }
379
380 /// Checks the security level of each available IRemotelyProvisionedComponent hal and returns
381 /// all levels in an array to the caller.
Max Biresd2ce46b2021-07-06 02:54:47 -0700382 pub fn get_implementation_info(&self) -> Result<Vec<ImplInfo>> {
383 Ok(self
384 .curve_by_sec_level
385 .iter()
386 .map(|(sec_level, curve)| ImplInfo { secLevel: *sec_level, supportedCurve: *curve })
387 .collect())
Max Bires148c08e2020-10-13 13:41:41 -0700388 }
Max Bires60d7ed12021-03-05 15:59:22 -0800389
390 /// Deletes all attestation keys generated by the IRemotelyProvisionedComponent from the device,
391 /// regardless of what state of the attestation key lifecycle they were in.
392 pub fn delete_all_keys(&self) -> Result<i64> {
393 DB.with::<_, Result<i64>>(|db| {
394 let mut db = db.borrow_mut();
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700395 db.delete_all_attestation_keys()
Max Bires60d7ed12021-03-05 15:59:22 -0800396 })
397 }
Max Bires148c08e2020-10-13 13:41:41 -0700398}
399
Hasini Gunasinghe8af67ea2021-06-30 17:09:01 +0000400/// Populates the AttestationPoolStatus parcelable with information about how many
401/// certs will be expiring by the date provided in `expired_by` along with how many
402/// keys have not yet been assigned.
403pub fn get_pool_status(expired_by: i64, sec_level: SecurityLevel) -> Result<AttestationPoolStatus> {
404 let (_, _, uuid) = get_keymint_device(&sec_level)?;
405 DB.with::<_, Result<AttestationPoolStatus>>(|db| {
406 let mut db = db.borrow_mut();
407 // delete_expired_attestation_keys is always safe to call, and will remove anything
408 // older than the date at the time of calling. No work should be done on the
409 // attestation keys unless the pool status is checked first, so this call should be
410 // enough to routinely clean out expired keys.
411 db.delete_expired_attestation_keys()?;
412 db.get_attestation_pool_status(expired_by, &uuid)
413 })
414}
415
Max Bires148c08e2020-10-13 13:41:41 -0700416impl binder::Interface for RemoteProvisioningService {}
417
418// Implementation of IRemoteProvisioning. See AIDL spec at
419// :aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
420impl IRemoteProvisioning for RemoteProvisioningService {
421 fn getPoolStatus(
422 &self,
423 expired_by: i64,
424 sec_level: SecurityLevel,
425 ) -> binder::public_api::Result<AttestationPoolStatus> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000426 let _wp = wd::watch_millis("IRemoteProvisioning::getPoolStatus", 500);
Hasini Gunasinghe8af67ea2021-06-30 17:09:01 +0000427 map_or_log_err(get_pool_status(expired_by, sec_level), Ok)
Max Bires148c08e2020-10-13 13:41:41 -0700428 }
429
430 fn generateCsr(
431 &self,
432 test_mode: bool,
433 num_csr: i32,
434 eek: &[u8],
435 challenge: &[u8],
436 sec_level: SecurityLevel,
Max Biresb2e1d032021-02-08 21:35:05 -0800437 protected_data: &mut ProtectedData,
Max Bires834dd362021-03-23 13:01:57 -0700438 device_info: &mut DeviceInfo,
Max Bires148c08e2020-10-13 13:41:41 -0700439 ) -> binder::public_api::Result<Vec<u8>> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000440 let _wp = wd::watch_millis("IRemoteProvisioning::generateCsr", 500);
Max Biresb2e1d032021-02-08 21:35:05 -0800441 map_or_log_err(
Max Bires834dd362021-03-23 13:01:57 -0700442 self.generate_csr(
443 test_mode,
444 num_csr,
445 eek,
446 challenge,
447 sec_level,
448 protected_data,
449 device_info,
450 ),
Max Biresb2e1d032021-02-08 21:35:05 -0800451 Ok,
452 )
Max Bires148c08e2020-10-13 13:41:41 -0700453 }
454
455 fn provisionCertChain(
456 &self,
457 public_key: &[u8],
Max Biresb2e1d032021-02-08 21:35:05 -0800458 batch_cert: &[u8],
Max Bires148c08e2020-10-13 13:41:41 -0700459 certs: &[u8],
460 expiration_date: i64,
461 sec_level: SecurityLevel,
462 ) -> binder::public_api::Result<()> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000463 let _wp = wd::watch_millis("IRemoteProvisioning::provisionCertChain", 500);
Max Biresb2e1d032021-02-08 21:35:05 -0800464 map_or_log_err(
465 self.provision_cert_chain(public_key, batch_cert, certs, expiration_date, sec_level),
466 Ok,
467 )
Max Bires148c08e2020-10-13 13:41:41 -0700468 }
469
470 fn generateKeyPair(
471 &self,
472 is_test_mode: bool,
473 sec_level: SecurityLevel,
474 ) -> binder::public_api::Result<()> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000475 let _wp = wd::watch_millis("IRemoteProvisioning::generateKeyPair", 500);
Max Bires148c08e2020-10-13 13:41:41 -0700476 map_or_log_err(self.generate_key_pair(is_test_mode, sec_level), Ok)
477 }
Max Biresb2e1d032021-02-08 21:35:05 -0800478
Max Biresd2ce46b2021-07-06 02:54:47 -0700479 fn getImplementationInfo(&self) -> binder::public_api::Result<Vec<ImplInfo>> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000480 let _wp = wd::watch_millis("IRemoteProvisioning::getSecurityLevels", 500);
Max Biresd2ce46b2021-07-06 02:54:47 -0700481 map_or_log_err(self.get_implementation_info(), Ok)
Max Biresb2e1d032021-02-08 21:35:05 -0800482 }
Max Bires60d7ed12021-03-05 15:59:22 -0800483
484 fn deleteAllKeys(&self) -> binder::public_api::Result<i64> {
Hasini Gunasinghe5a893e82021-05-05 14:32:32 +0000485 let _wp = wd::watch_millis("IRemoteProvisioning::deleteAllKeys", 500);
Max Bires60d7ed12021-03-05 15:59:22 -0800486 map_or_log_err(self.delete_all_keys(), Ok)
487 }
Max Bires148c08e2020-10-13 13:41:41 -0700488}