spideroak_crypto/
import.rs1use core::{
4 fmt::{self, Display},
5 ops::Range,
6 result::Result,
7};
8
9use buggy::Bug;
10use generic_array::{ArrayLength, GenericArray};
11
12use crate::signer::PkError;
13
14#[derive(Debug, Eq, PartialEq)]
16pub struct InvalidSizeError {
17 pub got: usize,
19 pub want: Range<usize>,
21}
22
23impl Display for InvalidSizeError {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(
26 f,
27 "invalid size data: got {}, want {}..{}",
28 self.got, self.want.start, self.want.end
29 )
30 }
31}
32
33impl core::error::Error for InvalidSizeError {}
34
35#[derive(Debug, Eq, PartialEq)]
37pub enum ImportError {
38 Other(&'static str),
40 InvalidSize(InvalidSizeError),
42 InvalidSyntax,
44 InvalidContext,
47 Bug(Bug),
49 PkError(PkError),
51}
52
53impl Display for ImportError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::Other(msg) => write!(f, "{}", msg),
57 Self::InvalidSize(err) => write!(f, "{}", err),
58 Self::InvalidSyntax => write!(f, "data is syntactically invalid"),
59 Self::InvalidContext => write!(f, "data came from a different context"),
60 Self::Bug(err) => write!(f, "{}", err),
61 Self::PkError(err) => write!(f, "{}", err),
62 }
63 }
64}
65
66impl core::error::Error for ImportError {
67 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
68 match self {
69 Self::InvalidSize(err) => Some(err),
70 Self::Bug(err) => Some(err),
71 _ => None,
72 }
73 }
74}
75
76impl From<InvalidSizeError> for ImportError {
77 fn from(err: InvalidSizeError) -> Self {
78 Self::InvalidSize(err)
79 }
80}
81
82impl From<Bug> for ImportError {
83 fn from(err: Bug) -> Self {
84 Self::Bug(err)
85 }
86}
87
88impl From<PkError> for ImportError {
89 fn from(err: PkError) -> Self {
90 Self::PkError(err)
91 }
92}
93
94pub fn try_from_slice<const N: usize>(data: &[u8]) -> Result<&[u8; N], InvalidSizeError> {
97 data.try_into().map_err(|_| InvalidSizeError {
98 got: data.len(),
99 want: N..N,
100 })
101}
102
103pub fn try_import<T, const N: usize>(data: &[u8]) -> Result<T, ImportError>
106where
107 T: Import<[u8; N]>,
108{
109 T::import(*try_from_slice(data)?)
110}
111
112impl<'a, const N: usize> Import<&'a [u8]> for &'a [u8; N] {
113 fn import(data: &[u8]) -> Result<&[u8; N], ImportError> {
114 data.try_into().map_err(|_| {
115 ImportError::InvalidSize(InvalidSizeError {
116 got: data.len(),
117 want: N..N,
118 })
119 })
120 }
121}
122
123impl<const N: usize> Import<&[u8]> for [u8; N] {
124 fn import(data: &[u8]) -> Result<Self, ImportError> {
125 let data: &[u8; N] = Import::<_>::import(data)?;
126 Ok(*data)
127 }
128}
129
130impl<const N: usize> Import<[u8; N]> for [u8; N] {
131 #[inline]
132 fn import(data: [u8; N]) -> Result<Self, ImportError> {
133 Ok(data)
134 }
135}
136
137impl<'a, N: ArrayLength> Import<&'a [u8]> for &'a GenericArray<u8, N> {
138 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
139 GenericArray::try_from_slice(data).map_err(|_| {
140 ImportError::InvalidSize(InvalidSizeError {
141 got: data.len(),
142 want: N::USIZE..N::USIZE,
143 })
144 })
145 }
146}
147
148impl<N: ArrayLength> Import<&[u8]> for GenericArray<u8, N> {
149 fn import(data: &[u8]) -> Result<Self, ImportError> {
150 let data: &GenericArray<u8, N> = Import::<_>::import(data)?;
151 Ok(data.clone())
152 }
153}
154
155impl<N: ArrayLength> Import<GenericArray<u8, N>> for GenericArray<u8, N> {
156 #[inline]
157 fn import(data: GenericArray<u8, N>) -> Result<Self, ImportError> {
158 Ok(data)
159 }
160}
161
162pub trait Import<T>: Sized {
164 fn import(data: T) -> Result<Self, ImportError>;
166}
167
168#[derive(Debug, Eq, PartialEq)]
170pub enum ExportError {
171 Other(&'static str),
173 Opaque,
175}
176
177impl Display for ExportError {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 match self {
180 Self::Other(msg) => write!(f, "{}", msg),
181 Self::Opaque => write!(f, "the key is opaque and cannot be exported"),
182 }
183 }
184}
185
186impl core::error::Error for ExportError {}