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 //! Data structures used in AuthMgr Backend 18 use crate::{ 19 am_err, 20 error::{Error, ErrorCode}, 21 traits::RawConnection, 22 }; 23 use alloc::boxed::Box; 24 use alloc::collections::VecDeque; 25 use alloc::sync::Arc; 26 use alloc::vec::Vec; 27 use authgraph_core::key::{CertChain, EcVerifyKey, InstanceIdentifier, Policy}; 28 use authmgr_common::{ 29 signed_connection_request::{Challenge, TransportID}, 30 Token, 31 }; 32 use log::warn; 33 34 /// Version of the data structure format used to store details of a persistent instance 35 pub const VERSION_PERSISTENT_INSTANCE_CONTEXT: i32 = 1; 36 /// Version of the data structure format used to store details of a persistent client 37 pub const VERSION_PERSISTENT_CLIENT_CONTEXT: i32 = 1; 38 39 /// Default value for maximum number of entries in the cache for authentication started pVMs 40 pub const MAX_SIZE_AUTH_STARTED_PVMS: usize = 6; 41 /// Default value for maximum number of entries in the cache for authenticated pVMs 42 pub const MAX_SIZE_AUTH_COMPLETED_PVMS: usize = 6; 43 /// Default value for the maximum number of entries in the cache for authorized clients 44 /// per connection 45 pub const MAX_AUTHORIZED_CLIENTS_PER_CONNECTION: usize = 8; 46 47 /// Type alias for a client identifier of 64 bytes. This identifier is assigned by the pVM. 48 #[derive(Clone, Debug, Eq, Hash, PartialEq)] 49 pub struct ClientId(pub Vec<u8>); 50 51 /// Information stored in an authenticated connection established between a pVM and the AuthMgr BE. 52 /// This information is re-used when serving multiple requests for authorizing the 53 /// clients in the pVM 54 pub struct AuthenticatedConnectionState { 55 /// Instance id of the pvm 56 pub instance_id: Arc<InstanceIdentifier>, 57 /// Transport id of the pvm 58 pub transport_id: TransportID, 59 /// Unique sequence number assigned to the instance by the AuthMgr BE 60 pub instance_seq_number: i32, 61 /// DICE artifacts of the pvm 62 pub dice_artifacts: DiceArtifacts, 63 /// Public key of the signing key pair of the pvm 64 pub pub_signing_key: EcVerifyKey, 65 /// Whether the pvm is persistent 66 pub is_persistent: bool, 67 /// Maximum number of clients allowed for the pvm 68 pub max_num_of_clients: usize, 69 /// Cache of the authorized clients of the pvm 70 pub authorized_clients: Vec<AuthorizedClient>, 71 } 72 73 impl AuthenticatedConnectionState { 74 /// Populate the information to be stored in-memory in the connection state new( instance_id: Arc<InstanceIdentifier>, transport_id: TransportID, instance_seq_number: i32, dice_artifacts: DiceArtifacts, pub_signing_key: EcVerifyKey, is_persistent: bool, max_num_of_clients: usize, ) -> Result<Self, Error>75 pub fn new( 76 instance_id: Arc<InstanceIdentifier>, 77 transport_id: TransportID, 78 instance_seq_number: i32, 79 dice_artifacts: DiceArtifacts, 80 pub_signing_key: EcVerifyKey, 81 is_persistent: bool, 82 max_num_of_clients: usize, 83 ) -> Result<Self, Error> { 84 let mut authorized_clients = Vec::<AuthorizedClient>::new(); 85 authorized_clients.try_reserve(max_num_of_clients)?; 86 Ok(Self { 87 instance_id, 88 transport_id, 89 instance_seq_number, 90 dice_artifacts, 91 pub_signing_key, 92 is_persistent, 93 max_num_of_clients, 94 authorized_clients, 95 }) 96 } 97 98 /// Given the client id, get the id information of the corresponding authorized client. get_mutable_authorized_client( &mut self, client_id: &ClientId, ) -> Option<&mut AuthorizedClient>99 pub fn get_mutable_authorized_client( 100 &mut self, 101 client_id: &ClientId, 102 ) -> Option<&mut AuthorizedClient> { 103 self.authorized_clients.iter_mut().find(|client| *client.client_id == *client_id) 104 } 105 106 /// Insert the authorized client into into the cache insert_authorized_client( &mut self, authorized_client: AuthorizedClient, ) -> Result<(), Error>107 pub fn insert_authorized_client( 108 &mut self, 109 authorized_client: AuthorizedClient, 110 ) -> Result<(), Error> { 111 if self 112 .authorized_clients 113 .iter() 114 .any(|client| client.sequence_number == authorized_client.sequence_number) 115 { 116 return Err(am_err!( 117 InternalError, 118 "a client with the given sequence number already exist in the cache" 119 )); 120 } 121 if self.authorized_clients.len() == self.max_num_of_clients { 122 return Err(am_err!( 123 MemoryAllocationFailed, 124 "Max limit for the authorized clients per connection reached." 125 )); 126 } 127 self.authorized_clients.push(authorized_client); 128 Ok(()) 129 } 130 } 131 132 /// Encapsulation of the DICE certificate chain and the DICE policy used to validate it 133 #[derive(Clone)] 134 pub struct DiceArtifacts { 135 /// DICE certificate chain 136 pub cert_chain: Arc<CertChain>, 137 /// DICE poicy 138 pub policy: Arc<Policy>, 139 } 140 141 /// Information associated with an authorized client. This information is used to check for 142 /// duplicate authorization attempts for the same client. 143 #[derive(Clone)] 144 pub struct AuthorizedClient { 145 /// Client id 146 pub client_id: Arc<ClientId>, 147 /// Unique sequence number assigned to the client by the AuthMgr BE 148 pub sequence_number: i32, 149 /// DICE policy of the client 150 pub policy: Arc<Policy>, 151 } 152 153 impl AuthorizedClient { 154 /// Update the client's policy with the given policy update_policy(&mut self, updated_policy: &Arc<Policy>)155 pub fn update_policy(&mut self, updated_policy: &Arc<Policy>) { 156 self.policy = Arc::clone(updated_policy); 157 } 158 } 159 160 /// Information of a persistent pvm instance stored in the persistent secure storage. 161 /// Deletion of the persistent instances (and clients) at runtime is not currently supported. 162 #[derive(Clone)] 163 pub struct PersistentInstanceContext { 164 /// Version of the data structure format 165 pub version: i32, 166 /// Unique sequence number of the persistent instance 167 pub sequence_number: i32, 168 /// DICE policy 169 pub dice_policy: Arc<Policy>, 170 } 171 172 /// Information of a persistent client stored in the persistent secure storage. 173 #[derive(Clone)] 174 pub struct PersistentClientContext { 175 /// Version of the data structure format 176 pub version: i32, 177 /// Unique sequence number of the persistent client 178 pub sequence_number: i32, 179 /// DICE policy 180 pub dice_policy: Arc<Policy>, 181 } 182 183 /// Encapsulates information about a pVM instance which has completed step 1 of phase 1 of the 184 /// AuthMgr protocol (i.e. `init_authentication`), but not step 2 (i.e. `complete_authentication`). 185 #[derive(Clone, PartialEq)] 186 pub struct AuthStartedPvm { 187 /// Transport id of the pvm (a.k.a. VM ID) 188 pub transport_id: TransportID, 189 /// Instance id of the pvm 190 pub instance_id: Arc<InstanceIdentifier>, 191 /// Challenge issued by the AuthMgr BE to this pvm 192 pub challenge: Challenge, 193 /// Certificate chain of the pvm 194 pub cert_chain: Arc<CertChain>, 195 } 196 197 impl AuthStartedPvm { 198 /// Perform state transition of an AuthStartedPvm. mark_as_authenticated( &self, auth_started_pvms: &mut AuthStartedPvms, authenticated_pvms: &mut AuthenticatedPvms, ) -> Result<(), Error>199 pub fn mark_as_authenticated( 200 &self, 201 auth_started_pvms: &mut AuthStartedPvms, 202 authenticated_pvms: &mut AuthenticatedPvms, 203 ) -> Result<(), Error> { 204 // Remove any other entries in `AuthStartedPvms` with the authenticated instance id, to 205 // enforce the Trust On First Use (TOFU) principle. 206 auth_started_pvms.remove_via_instance_id(&self.instance_id); 207 authenticated_pvms.insert(self) 208 } 209 } 210 211 /// A list of pVMs which have initiated authentication, but not have completed authentication. 212 pub struct AuthStartedPvms { 213 /// The number of allowed authentication started pvms at a given time 214 capacity: usize, 215 /// The list of authentication started pvms 216 auth_started_pvms: VecDeque<AuthStartedPvm>, 217 } 218 219 impl AuthStartedPvms { 220 /// Constructor new(capacity: usize) -> Result<Self, Error>221 pub fn new(capacity: usize) -> Result<Self, Error> { 222 let mut auth_started_pvms = VecDeque::new(); 223 auth_started_pvms.try_reserve(capacity)?; 224 Ok(AuthStartedPvms { capacity, auth_started_pvms }) 225 } 226 227 /// Insert a new entry to the list insert(&mut self, auth_started_pvm: AuthStartedPvm)228 pub fn insert(&mut self, auth_started_pvm: AuthStartedPvm) { 229 if self.auth_started_pvms.len() == self.capacity { 230 // Here we remove the oldest entry instead of returning an error in order to prevent 231 // genuine pvms from being denied from starting authentication due to `AuthStartedPvms` 232 // being filled up to the capacity - which can be caused by both malicious activity and 233 // non-malicious activity (e.g. a pvm starts authentication, but never completes). 234 warn!("Maximum number of auth started pvms reached. Removing the oldest one."); 235 self.auth_started_pvms.pop_front(); 236 } 237 self.auth_started_pvms.push_back(auth_started_pvm); 238 } 239 240 /// Check if an entry with a given transport id already exists in the list - this is used to 241 /// prevent duplicated authentication attempts from the same instance. has_transport_id(&self, transport_id: TransportID) -> bool242 pub fn has_transport_id(&self, transport_id: TransportID) -> bool { 243 self.auth_started_pvms.iter().any(|entry| entry.transport_id == transport_id) 244 } 245 246 /// Take an entry out of the list via its transport id - this is used to retrieve the required 247 /// information to perform step 2 of phase 1 for those who have performed step 1 of phase 1. take_via_transport_id(&mut self, transport_id: TransportID) -> Option<AuthStartedPvm>248 pub fn take_via_transport_id(&mut self, transport_id: TransportID) -> Option<AuthStartedPvm> { 249 let index = 250 self.auth_started_pvms.iter().position(|entry| entry.transport_id == transport_id); 251 index.map(|index| self.auth_started_pvms.remove(index))? 252 } 253 254 /// Remove an entry via its transport id - this is used to remove an entry when only the 255 /// transport id is available - e.g. upon connection close. remove_via_transport_id(&mut self, transport_id: TransportID)256 pub fn remove_via_transport_id(&mut self, transport_id: TransportID) { 257 self.auth_started_pvms.retain(|entry| entry.transport_id != transport_id); 258 } 259 260 /// Remove all entries with a given instance id - this is used to remove all entries with 261 /// an authenticated instance id. remove_via_instance_id(&mut self, instance_id: &InstanceIdentifier)262 pub fn remove_via_instance_id(&mut self, instance_id: &InstanceIdentifier) { 263 self.auth_started_pvms.retain(|entry| &*entry.instance_id != instance_id); 264 } 265 } 266 267 /// Encapsulates information about a pVM instance which has completed phase 1 of the AuthMgr 268 /// protocol 269 #[derive(PartialEq)] 270 pub struct AuthenticatedPvm { 271 /// Instance id of the pvm 272 pub instance_id: Arc<InstanceIdentifier>, 273 /// Transport id of the pvm 274 pub transport_id: TransportID, 275 } 276 277 /// A list of pVMs which have completed authentication 278 pub struct AuthenticatedPvms { 279 /// The number of allowed authentication completed pvms at a given time 280 capacity: usize, 281 /// List of authentication completed pvms 282 authenticated_pvms: Vec<AuthenticatedPvm>, 283 } 284 285 impl AuthenticatedPvms { 286 /// Constructor new(capacity: usize) -> Result<Self, Error>287 pub fn new(capacity: usize) -> Result<Self, Error> { 288 let mut authenticated_pvms = Vec::<AuthenticatedPvm>::new(); 289 authenticated_pvms.try_reserve(capacity)?; 290 Ok(AuthenticatedPvms { capacity, authenticated_pvms }) 291 } 292 293 /// Insert a new entry to the list, constructed from the given AuthStartedPvm insert(&mut self, auth_started_pvm: &AuthStartedPvm) -> Result<(), Error>294 pub fn insert(&mut self, auth_started_pvm: &AuthStartedPvm) -> Result<(), Error> { 295 if self.authenticated_pvms.len() == self.capacity { 296 return Err(am_err!( 297 MemoryAllocationFailed, 298 "Maximum number of authenticated pvms reached." 299 )); 300 } 301 let authenticated_pvm = AuthenticatedPvm { 302 instance_id: Arc::clone(&auth_started_pvm.instance_id), 303 transport_id: auth_started_pvm.transport_id, 304 }; 305 self.authenticated_pvms.push(authenticated_pvm); 306 Ok(()) 307 } 308 309 /// Check if a pvm with a given instance id already exists in the list - this is used to prevent 310 /// duplicated authentication attempts has_instance_id(&self, instance_id: &InstanceIdentifier) -> bool311 pub fn has_instance_id(&self, instance_id: &InstanceIdentifier) -> bool { 312 self.authenticated_pvms.iter().any(|entry| &*entry.instance_id == instance_id) 313 } 314 315 /// Check if a pvm with a given transport id already exists in the list - this is used to 316 /// ensure that step 1 of phase 2 of the AuthMgr protocol is allowed only for already 317 /// authenticated instances has_transport_id(&self, transport_id: TransportID) -> bool318 pub fn has_transport_id(&self, transport_id: TransportID) -> bool { 319 self.authenticated_pvms.iter().any(|entry| entry.transport_id == transport_id) 320 } 321 322 /// Remove a pvm instance via its transport id (upon connection close) remove_via_transport_id(&mut self, transport_id: TransportID)323 pub fn remove_via_transport_id(&mut self, transport_id: TransportID) { 324 self.authenticated_pvms.retain(|entry| entry.transport_id != transport_id); 325 } 326 } 327 328 /// The in-memory data structure representing a new connection requested for a client in step 1 of 329 /// phase 2 of the AuthMgr protocol. The token is used to authorize this new connection. 330 /// The same token should be sent over an already authenticated connection setup between AuthMgr FE 331 /// and AuthMgr BE. 332 pub struct PendingClientAuthorization { 333 /// Token used to authorize a connection 334 pub token: Token, 335 /// Client connection 336 pub client_connection: Box<dyn RawConnection>, 337 } 338 339 impl PendingClientAuthorization { 340 /// Constructor for a pending client authorization new(token: Token, client_connection: Box<dyn RawConnection>) -> Self341 pub fn new(token: Token, client_connection: Box<dyn RawConnection>) -> Self { 342 PendingClientAuthorization { token, client_connection } 343 } 344 } 345 346 /// The in-memory data structure to keep track of the new connections requested by a particular pVM 347 /// (identified by the transport id), on behalf of a client. The limit for the number of connections 348 /// allowed per pVM should be specified when initializing the AuthMgr BE. 349 pub struct PendingClientAuthorizationsPerPvm { 350 /// Transport id of the pvm 351 transport_id: TransportID, 352 /// List of authentication completed pvms 353 capacity: usize, 354 /// A list of client connections pending authorization 355 pending_clients: Vec<PendingClientAuthorization>, 356 } 357 358 impl PendingClientAuthorizationsPerPvm { 359 /// Constructor new(transport_id: TransportID, capacity: usize) -> Result<Self, Error>360 pub fn new(transport_id: TransportID, capacity: usize) -> Result<Self, Error> { 361 let mut pending_clients = Vec::<PendingClientAuthorization>::new(); 362 pending_clients.try_reserve(capacity)?; 363 Ok(PendingClientAuthorizationsPerPvm { transport_id, capacity, pending_clients }) 364 } 365 366 /// Insert a new entry to the list insert( &mut self, pending_client_authorization: PendingClientAuthorization, ) -> Result<(), Error>367 pub fn insert( 368 &mut self, 369 pending_client_authorization: PendingClientAuthorization, 370 ) -> Result<(), Error> { 371 if self.pending_clients.len() == self.capacity { 372 return Err(am_err!( 373 MemoryAllocationFailed, 374 "Maximum capacity reached for the pending authorizations for the pVM with the 375 transport id: {:?}.", 376 self.transport_id 377 )); 378 } 379 if self 380 .pending_clients 381 .iter() 382 .any(|client| client.token == pending_client_authorization.token) 383 { 384 return Err(am_err!( 385 InternalError, 386 "a pending client authorzation with the given tokan already exists" 387 )); 388 } 389 self.pending_clients.push(pending_client_authorization); 390 Ok(()) 391 } 392 393 /// Take an entry out of the list, given the token take(&mut self, token: Token) -> Option<PendingClientAuthorization>394 pub fn take(&mut self, token: Token) -> Option<PendingClientAuthorization> { 395 let index = self 396 .pending_clients 397 .iter() 398 .position(|pending_authorization| pending_authorization.token == token); 399 index.map(|index| self.pending_clients.remove(index)) 400 } 401 } 402 403 /// The in-memory data structure that stores the new connections requested from different pVMs 404 /// on behalf of the clients, to be authorized and handed over to the trusted services. 405 /// The limit for the number of entries should be the same as the limit for the authenticated pVMs. 406 /// We use a separate data structure rather than using `AuthenticatedPvms` or `AuthenticatedPvm` 407 /// because at the time the requests for initiating a new connection for a client comes in, 408 /// we do not know whether it is coming from an "authenticated AuthMgr FE component" in the pVM. 409 pub struct PendingClientAuthorizations { 410 /// The allowed number of pvms 411 capacity: usize, 412 /// The allowed number of pending connections per pvm 413 max_entries_per_pvm: usize, 414 /// List of pending client connections categorized by pvm 415 pending_clients_by_pvm: Vec<PendingClientAuthorizationsPerPvm>, 416 } 417 418 impl PendingClientAuthorizations { 419 /// Constructor for PendingClientAuthorizations new(capacity: usize, max_entries_per_pvm: usize) -> Result<Self, Error>420 pub fn new(capacity: usize, max_entries_per_pvm: usize) -> Result<Self, Error> { 421 let mut pending_clients_by_pvm = Vec::<PendingClientAuthorizationsPerPvm>::new(); 422 pending_clients_by_pvm.try_reserve(capacity)?; 423 Ok(PendingClientAuthorizations { capacity, max_entries_per_pvm, pending_clients_by_pvm }) 424 } 425 426 /// Insert a pending client authorization insert( &mut self, transport_id: TransportID, pending_client_authorization: PendingClientAuthorization, ) -> Result<(), Error>427 pub fn insert( 428 &mut self, 429 transport_id: TransportID, 430 pending_client_authorization: PendingClientAuthorization, 431 ) -> Result<(), Error> { 432 let per_pvm_entry: Option<&mut PendingClientAuthorizationsPerPvm> = 433 self.pending_clients_by_pvm.iter_mut().find(|entry| entry.transport_id == transport_id); 434 match per_pvm_entry { 435 Some(per_pvm_entry) => { 436 per_pvm_entry.insert(pending_client_authorization)?; 437 } 438 None => { 439 if self.pending_clients_by_pvm.len() == self.capacity { 440 return Err(am_err!( 441 MemoryAllocationFailed, 442 "Maximum capacity reached for the number of pVMs that can accept 443 pending authorizations." 444 )); 445 } 446 let mut pending_clients_for_pvm = 447 PendingClientAuthorizationsPerPvm::new(transport_id, self.max_entries_per_pvm)?; 448 pending_clients_for_pvm.insert(pending_client_authorization)?; 449 self.pending_clients_by_pvm.push(pending_clients_for_pvm); 450 } 451 } 452 Ok(()) 453 } 454 455 /// Take the pending client authorization that matches the transport id and the token take( &mut self, transport_id: TransportID, token: Token, ) -> Option<PendingClientAuthorization>456 pub fn take( 457 &mut self, 458 transport_id: TransportID, 459 token: Token, 460 ) -> Option<PendingClientAuthorization> { 461 self.pending_clients_by_pvm 462 .iter_mut() 463 .find(|per_pvm_list| per_pvm_list.transport_id == transport_id) 464 .map(|pending_authorizations_per_pvm| pending_authorizations_per_pvm.take(token))? 465 } 466 467 /// Remove all the connections identified by the transport id remove_via_transport_id(&mut self, transport_id: TransportID)468 pub fn remove_via_transport_id(&mut self, transport_id: TransportID) { 469 self.pending_clients_by_pvm 470 .retain(|pending_clients_per_pvm| pending_clients_per_pvm.transport_id != transport_id); 471 } 472 } 473 474 /// Encapsulation of the full DICE artifacts of a client. This is particularly required for the 475 /// "policy matching as a service" provided by AuthMgr BE. 476 pub struct AuthorizedClientFullDiceArtifacts { 477 /// Unique sequence number of the client 478 pub sequence_number: i32, 479 /// Transport id of the pvm that the client belongs to (used to cleanup the cache upon 480 /// connection close by the pvm) 481 pub transport_id: TransportID, 482 /// Client's id (used to cleanup the cache upon client deletion) 483 pub client_id: Arc<ClientId>, 484 /// Complete DICE artifacts of the client 485 pub full_dice_artifacts: DiceArtifacts, 486 } 487 488 /// List of authorized clients with their full DICE artifacts. This is particularly required for the 489 /// "policy matching as a service" provided by AuthMgr BE. 490 pub struct AuthorizedClientsGlobalList { 491 /// Allowed number of authorized clients 492 capacity: usize, 493 /// List of authorized clients with their complete set of DICE artifacts (i.e. the leaf DICE 494 /// artifacts combined with the pvm DICE artifacts) 495 authorized_clients_list: Vec<AuthorizedClientFullDiceArtifacts>, 496 } 497 498 impl AuthorizedClientsGlobalList { 499 /// Constructor new(capacity: usize) -> Result<Self, Error>500 pub fn new(capacity: usize) -> Result<Self, Error> { 501 let mut authorized_clients_list = Vec::<AuthorizedClientFullDiceArtifacts>::new(); 502 authorized_clients_list.try_reserve(capacity)?; 503 Ok(AuthorizedClientsGlobalList { capacity, authorized_clients_list }) 504 } 505 506 /// Retrieve a mutable client given the client's unique sequence number get_mut(&mut self, seq_number: i32) -> Option<&mut AuthorizedClientFullDiceArtifacts>507 pub fn get_mut(&mut self, seq_number: i32) -> Option<&mut AuthorizedClientFullDiceArtifacts> { 508 self.authorized_clients_list 509 .iter_mut() 510 .find(|authorized_client| authorized_client.sequence_number == seq_number) 511 } 512 513 /// Insert a new entry to the list insert( &mut self, authorized_client_full_dice_artifacts: AuthorizedClientFullDiceArtifacts, ) -> Result<(), Error>514 pub fn insert( 515 &mut self, 516 authorized_client_full_dice_artifacts: AuthorizedClientFullDiceArtifacts, 517 ) -> Result<(), Error> { 518 if self.authorized_clients_list.iter().any(|authorized_client| { 519 authorized_client.sequence_number 520 == authorized_client_full_dice_artifacts.sequence_number 521 }) { 522 return Err(am_err!( 523 InternalError, 524 "full dice artifacts already exists for the unique client sequence number: {:?}.", 525 authorized_client_full_dice_artifacts.sequence_number 526 )); 527 } 528 if self.authorized_clients_list.len() == self.capacity { 529 return Err(am_err!( 530 MemoryAllocationFailed, 531 "Capacity for the global list of authorized clients reached." 532 )); 533 } 534 self.authorized_clients_list.push(authorized_client_full_dice_artifacts); 535 Ok(()) 536 } 537 538 /// Remove all entries given a transport id remove_via_transport_id(&mut self, transport_id: TransportID)539 pub fn remove_via_transport_id(&mut self, transport_id: TransportID) { 540 self.authorized_clients_list 541 .retain(|authorized_clients| authorized_clients.transport_id != transport_id); 542 } 543 544 /// Remove an entry given the client id remove_via_client_id(&mut self, client_id: &ClientId)545 pub fn remove_via_client_id(&mut self, client_id: &ClientId) { 546 self.authorized_clients_list 547 .retain(|authorized_clients| *authorized_clients.client_id == *client_id); 548 } 549 } 550 551 /// Max sizes of the in-memory data structures to be specified by the implementation of 552 /// the AuthMgrBE. These numbers may depend on the max number of connections supported by the TEE 553 /// per process. 554 pub struct MemoryLimits { 555 /// Capacity of the AuthStartedPvms list 556 pub capacity_auth_started_pvms: usize, 557 /// Capacity of the AuthCompletedPvms list 558 pub capacity_auth_completed_pvms: usize, 559 /// Number of clients allowed per pvm 560 pub max_clients_per_pvm: usize, 561 } 562 563 impl Default for MemoryLimits { default() -> Self564 fn default() -> Self { 565 Self { 566 capacity_auth_started_pvms: MAX_SIZE_AUTH_STARTED_PVMS, 567 capacity_auth_completed_pvms: MAX_SIZE_AUTH_COMPLETED_PVMS, 568 max_clients_per_pvm: MAX_AUTHORIZED_CLIENTS_PER_CONNECTION, 569 } 570 } 571 } 572