1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //! Common functionality for non-secure/testing instance of AuthGraph. 18 19 use authgraph_boringssl as boring; 20 use authgraph_core::{ 21 error, keyexchange, 22 ta::{AuthGraphTa, Role}, 23 }; 24 use authgraph_hal::channel::SerializedChannel; 25 use log::error; 26 use std::cell::RefCell; 27 use std::rc::Rc; 28 use std::sync::{mpsc, Mutex}; 29 30 /// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore 31 /// insecure). 32 pub struct LocalTa { 33 channels: Mutex<Channels>, 34 } 35 36 struct Channels { 37 in_tx: mpsc::Sender<Vec<u8>>, 38 out_rx: mpsc::Receiver<Vec<u8>>, 39 } 40 41 impl LocalTa { 42 /// Create a new instance. new() -> Result<Self, error::Error>43 pub fn new() -> Result<Self, error::Error> { 44 // Create a pair of channels to communicate with the TA thread. 45 let (in_tx, in_rx) = mpsc::channel(); 46 let (out_tx, out_rx) = mpsc::channel(); 47 48 // The TA code expects to run single threaded, so spawn a thread to run it in. 49 std::thread::spawn(move || { 50 let mut ta = AuthGraphTa::new( 51 keyexchange::AuthGraphParticipant::new( 52 boring::crypto_trait_impls(), 53 Rc::new(RefCell::new(boring::test_device::AgDevice::default())), 54 keyexchange::MAX_OPENED_SESSIONS, 55 ) 56 .expect("failed to create AG participant"), 57 Role::Both, 58 ); 59 // Loop forever processing request messages. 60 loop { 61 let req_data: Vec<u8> = match in_rx.recv() { 62 Ok(data) => data, 63 Err(_) => { 64 error!("local TA failed to receive request!"); 65 break; 66 } 67 }; 68 let rsp_data = ta.process(&req_data); 69 match out_tx.send(rsp_data) { 70 Ok(_) => {} 71 Err(_) => { 72 error!("local TA failed to send out response"); 73 break; 74 } 75 } 76 } 77 error!("local TA terminating!"); 78 }); 79 Ok(Self { 80 channels: Mutex::new(Channels { in_tx, out_rx }), 81 }) 82 } 83 } 84 85 impl SerializedChannel for LocalTa { 86 const MAX_SIZE: usize = usize::MAX; 87 execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>>88 fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> { 89 // Serialize across both request and response. 90 let channels = self.channels.lock().unwrap(); 91 channels 92 .in_tx 93 .send(req_data.to_vec()) 94 .expect("failed to send in request"); 95 Ok(channels.out_rx.recv().expect("failed to receive response")) 96 } 97 } 98