Skip to main content

trussed_wrap_key_to_file/
lib.rs

1// Copyright (C) Nitrokey GmbH
2// SPDX-License-Identifier: Apache-2.0 or MIT
3
4#![no_std]
5#![warn(non_ascii_idents, trivial_casts, unused, unused_qualifications)]
6#![deny(unsafe_code)]
7
8use serde::{Deserialize, Serialize};
9use trussed_core::{
10    serde_extensions::{Extension, ExtensionClient, ExtensionResult},
11    types::{Bytes, KeyId, Location, Mechanism, PathBuf},
12    ClientError,
13};
14
15#[derive(Debug, Default)]
16pub struct WrapKeyToFileExtension;
17
18#[derive(Debug, Deserialize, Serialize)]
19#[allow(missing_docs)]
20pub enum WrapKeyToFileRequest {
21    WrapKeyToFile(request::WrapKeyToFile),
22    UnwrapKeyFromFile(request::UnwrapKeyFromFile),
23}
24
25pub mod request {
26    use super::*;
27    use serde::{Deserialize, Serialize};
28    use trussed_core::types::{KeyId, Location, Mechanism, Message, PathBuf};
29    use trussed_core::Error;
30
31    #[derive(Debug, Deserialize, Serialize)]
32    pub struct WrapKeyToFile {
33        pub mechanism: Mechanism,
34        pub wrapping_key: KeyId,
35        pub key: KeyId,
36        pub path: PathBuf,
37        pub location: Location,
38        pub associated_data: Message,
39    }
40
41    impl TryFrom<WrapKeyToFileRequest> for WrapKeyToFile {
42        type Error = Error;
43        fn try_from(request: WrapKeyToFileRequest) -> Result<Self, Self::Error> {
44            match request {
45                WrapKeyToFileRequest::WrapKeyToFile(request) => Ok(request),
46                _ => Err(Error::InternalError),
47            }
48        }
49    }
50
51    impl From<WrapKeyToFile> for WrapKeyToFileRequest {
52        fn from(request: WrapKeyToFile) -> Self {
53            Self::WrapKeyToFile(request)
54        }
55    }
56
57    #[derive(Debug, Deserialize, Serialize)]
58    pub struct UnwrapKeyFromFile {
59        pub mechanism: Mechanism,
60        pub key: KeyId,
61        pub path: PathBuf,
62        pub file_location: Location,
63        pub key_location: Location,
64        pub associated_data: Message,
65    }
66
67    impl TryFrom<WrapKeyToFileRequest> for UnwrapKeyFromFile {
68        type Error = Error;
69        fn try_from(request: WrapKeyToFileRequest) -> Result<Self, Self::Error> {
70            match request {
71                WrapKeyToFileRequest::UnwrapKeyFromFile(request) => Ok(request),
72                _ => Err(Error::InternalError),
73            }
74        }
75    }
76
77    impl From<UnwrapKeyFromFile> for WrapKeyToFileRequest {
78        fn from(request: UnwrapKeyFromFile) -> Self {
79            Self::UnwrapKeyFromFile(request)
80        }
81    }
82}
83
84#[derive(Debug, Deserialize, Serialize)]
85#[allow(missing_docs)]
86pub enum WrapKeyToFileReply {
87    WrapKeyToFile(reply::WrapKeyToFile),
88    UnwrapKeyFromFile(reply::UnwrapKeyFromFile),
89}
90
91pub mod reply {
92    use serde::{Deserialize, Serialize};
93    use trussed_core::{types::KeyId, Error};
94
95    use super::*;
96
97    #[derive(Debug, Deserialize, Serialize, Default)]
98    pub struct WrapKeyToFile {}
99
100    impl TryFrom<WrapKeyToFileReply> for WrapKeyToFile {
101        type Error = Error;
102        fn try_from(reply: WrapKeyToFileReply) -> Result<Self, Self::Error> {
103            match reply {
104                WrapKeyToFileReply::WrapKeyToFile(reply) => Ok(reply),
105                _ => Err(Error::InternalError),
106            }
107        }
108    }
109
110    impl From<WrapKeyToFile> for WrapKeyToFileReply {
111        fn from(reply: WrapKeyToFile) -> Self {
112            Self::WrapKeyToFile(reply)
113        }
114    }
115
116    #[derive(Debug, Deserialize, Serialize)]
117    pub struct UnwrapKeyFromFile {
118        pub key: Option<KeyId>,
119    }
120
121    impl TryFrom<WrapKeyToFileReply> for UnwrapKeyFromFile {
122        type Error = Error;
123        fn try_from(reply: WrapKeyToFileReply) -> Result<Self, Self::Error> {
124            match reply {
125                WrapKeyToFileReply::UnwrapKeyFromFile(reply) => Ok(reply),
126                _ => Err(Error::InternalError),
127            }
128        }
129    }
130
131    impl From<UnwrapKeyFromFile> for WrapKeyToFileReply {
132        fn from(reply: UnwrapKeyFromFile) -> Self {
133            Self::UnwrapKeyFromFile(reply)
134        }
135    }
136}
137
138impl Extension for WrapKeyToFileExtension {
139    type Request = WrapKeyToFileRequest;
140    type Reply = WrapKeyToFileReply;
141}
142
143pub type WrapKeyToFileResult<'a, R, C> = ExtensionResult<'a, WrapKeyToFileExtension, R, C>;
144
145pub trait WrapKeyToFileClient: ExtensionClient<WrapKeyToFileExtension> {
146    /// Wrap a key to a file
147    /// This enables wrapping keys that don't fit in the buffers used by
148    /// [`write_file`](trussed_core::FilesystemClient::write_file) and [`read_file`](trussed_core::FilesystemClient::read_file)
149    fn wrap_key_to_file(
150        &mut self,
151        mechanism: Mechanism,
152        wrapping_key: KeyId,
153        key: KeyId,
154        path: PathBuf,
155        location: Location,
156        associated_data: &[u8],
157    ) -> WrapKeyToFileResult<'_, reply::WrapKeyToFile, Self> {
158        let associated_data =
159            Bytes::try_from(associated_data).map_err(|_| ClientError::DataTooLarge)?;
160        self.extension(request::WrapKeyToFile {
161            mechanism,
162            wrapping_key,
163            key,
164            path,
165            location,
166            associated_data,
167        })
168    }
169
170    /// Wrap a key to a file
171    /// This enables wrapping keys that don't fit in the buffers used by
172    /// [`write_file`](trussed_core::FilesystemClient::write_file) and [`read_file`](trussed_core::FilesystemClient::read_file)
173    fn unwrap_key_from_file(
174        &mut self,
175        mechanism: Mechanism,
176        key: KeyId,
177        path: PathBuf,
178        file_location: Location,
179        key_location: Location,
180        associated_data: &[u8],
181    ) -> WrapKeyToFileResult<'_, reply::UnwrapKeyFromFile, Self> {
182        let associated_data =
183            Bytes::try_from(associated_data).map_err(|_| ClientError::DataTooLarge)?;
184        self.extension(request::UnwrapKeyFromFile {
185            mechanism,
186            key,
187            path,
188            file_location,
189            key_location,
190            associated_data,
191        })
192    }
193}
194
195impl<C: ExtensionClient<WrapKeyToFileExtension>> WrapKeyToFileClient for C {}