1 // Copyright 2025 Google LLC
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 ////////////////////////////////////////////////////////////////////////////////
16
17 //! Crate containing the example/mock implementations of some of the AuthMgr BE traits for testing
18 //! purposes. These are the traits that can be implemented (mostly) independent of a concrete
19 //! AuthMgr TA running in the TEE environment. For e.g. Crypto traits, Device trait (without the
20 //! connection handover functionality) and the *Storage traits.
21 //! This crate calls into the generic tests provided by the `libauthmgr_be_test` crate in order to
22 //! run unit tests using the aforementioned (example) trait implementations.
23 extern crate alloc;
24 use authgraph_boringssl::{ec::BoringEcDsa, BoringRng};
25 use authgraph_core::key::{CertChain, InstanceIdentifier, Policy};
26 use authmgr_be::error::Error;
27 use authmgr_be::traits::{CryptoTraitImpl, Device, RawConnection};
28 use authmgr_common::{match_dice_chain_with_policy, signed_connection_request::TransportID};
29 use std::collections::HashMap;
30
31 pub mod mock_storage;
32
33 /// Return a populated [`CryptoTraitImpl`] structure that uses BoringSSL implementations for
34 /// cryptographic traits.
crypto_trait_impls() -> CryptoTraitImpl35 pub fn crypto_trait_impls() -> CryptoTraitImpl {
36 CryptoTraitImpl { ecdsa: Box::new(BoringEcDsa), rng: Box::new(BoringRng) }
37 }
38
39 /// Struct representing the state used to provide a mock implementation of AuthMgr `Device`` trait
40 #[derive(Default)]
41 pub struct AuthMgrBeDevice {
42 /// Transport ID of AuthMgr BE
43 pub transport_id: TransportID,
44 /// List of persistent instances allowed along with the DICE policies.
45 pub allowed_persistent_instances: HashMap<InstanceIdentifier, Policy>,
46 }
47
48 impl AuthMgrBeDevice {
49 /// Constructor
new( transport_id: TransportID, allowed_persistent_instances: HashMap<InstanceIdentifier, Policy>, ) -> Self50 pub fn new(
51 transport_id: TransportID,
52 allowed_persistent_instances: HashMap<InstanceIdentifier, Policy>,
53 ) -> Self {
54 Self { transport_id, allowed_persistent_instances }
55 }
56 }
57
58 impl Device for AuthMgrBeDevice {
59 /// Return the transport ID of the AuthMgr BE
get_self_transport_id(&self) -> Result<TransportID, Error>60 fn get_self_transport_id(&self) -> Result<TransportID, Error> {
61 Ok(self.transport_id)
62 }
63
64 /// Secure storage invariant: we cannot allow a non-persistent pVM connect to secure storage
65 /// without the secure storage knowing that it is a non-persistent client. Therefore, the
66 /// AuthMgr BE should know whether a given pVM is persistent. In the first version of the
67 /// trusted HAL project, we only support persistent pVM clients, therefore, in the first
68 /// version, this could simply return true. When non-persistent pVMs are supported, it is
69 /// expected that the AuthMgr BE learns via some out-of-band mechanism the instance ids of the
70 /// peristence pVMs on the device.
is_persistent_instance(&self, instance_id: &InstanceIdentifier) -> Result<bool, Error>71 fn is_persistent_instance(&self, instance_id: &InstanceIdentifier) -> Result<bool, Error> {
72 Ok(self.allowed_persistent_instances.contains_key(instance_id))
73 }
74
75 /// Connect to the trusted service identified by `service_name` and hand over the client
76 /// connection along with the unique client id.
handover_client_connection( &self, _service_name: &str, _client_seq_number: i32, _client_conn_handle: Box<dyn RawConnection>, _is_persistent: bool, ) -> Result<(), Error>77 fn handover_client_connection(
78 &self,
79 _service_name: &str,
80 _client_seq_number: i32,
81 _client_conn_handle: Box<dyn RawConnection>,
82 _is_persistent: bool,
83 ) -> Result<(), Error> {
84 // The mock implementation cannot do connection handover
85 Ok(())
86 }
87
88 /// Check whether the persistent instance with the given instance id and the dice cert chain is
89 /// allowed to be created.s
is_persistent_instance_creation_allowed( &self, instance_id: &InstanceIdentifier, dice_chain: &CertChain, ) -> Result<bool, Error>90 fn is_persistent_instance_creation_allowed(
91 &self,
92 instance_id: &InstanceIdentifier,
93 dice_chain: &CertChain,
94 ) -> Result<bool, Error> {
95 Ok(match_dice_chain_with_policy(
96 dice_chain,
97 self.allowed_persistent_instances.get(instance_id).unwrap(),
98 )?)
99 }
100 }
101
102 #[cfg(test)]
103 mod tests;
104