1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Security fetcher definitio
use async_trait::async_trait;

/// Security Fetcher Interface
///
/// This trait defines the interface for implementing a custom security fetcher, responsible for obtaining the
/// private key from the specifications of the device. By implementing this trait, you can define a specific process
/// for retrieving the private key securely, such as utilizing a Trusted Platform Module (TPM) or other dedicated
/// security hardware.
///
/// # Asynchronous Fetching
///
/// The method `read_private_key` is asynchronous, indicated by the [`async_trait`](https://crates.io/crates/async-trait) attribute.
/// It asynchronously returns a [`Vec`] of bytes (`u8`), representing the private key. Implementers of this trait can
/// perform asynchronous operations, such as reading the key from a file, fetching it from a remote service, or using
/// any other asynchronous mechanism.
///
/// # Errors
///
/// The `read_private_key` method may return an [`std::io::Error`] if any I/O operation fails during the fetching process.
#[async_trait]
pub trait SecurityFetcher {
    /// Returns a [`Vec`] of bytes representing the private key from the implementation.
    ///
    /// # Errors
    ///
    /// During the fetching process, an [`std::io::Error`] can occur if any I/O operation fails.
    async fn read_private_key(&self) -> Result<Vec<u8>, std::io::Error>;
}

/// Security Fetcher default read file implementation
///
/// This implementation of the `SecurityFetcher` allows to use a file to fetch the private key from your device.
pub struct SecurityFileFetcher {
    /// Private key's path
    path: String,
}

impl SecurityFileFetcher {
    /// Create basic Security that fetch a file
    pub fn new<S: Into<String>>(path: S) -> Self {
        Self { path: path.into() }
    }

    /// Create a boxed basic Security that fetch a file
    pub fn new_boxed<S: Into<String>>(path: S) -> Box<Self> {
        Box::new(Self::new(path))
    }
}

#[async_trait]
impl SecurityFetcher for SecurityFileFetcher {
    async fn read_private_key(&self) -> Result<Vec<u8>, std::io::Error> {
        use tokio::fs;
        fs::read(self.path.clone()).await
    }
}