bitwarden_crypto/
content_format.rs1use bitwarden_encoding::B64;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 CryptoError, EncString, KeyEncryptable, KeyEncryptableWithContentType, KeyIds, KeyStoreContext,
6 PrimitiveEncryptable, SymmetricCryptoKey, traits::PrimitiveEncryptableWithContentType,
7};
8
9#[derive(Clone, Copy, Debug, PartialEq)]
16pub(crate) enum ContentFormat {
17 Utf8,
19 Pkcs8PrivateKey,
21 SPKIPublicKeyDer,
23 CoseKey,
25 CoseSign1,
27 CoseEncrypt0,
29 BitwardenLegacyKey,
35 OctetStream,
37 Cbor,
39}
40
41mod private {
42 pub trait Sealed {}
45}
46
47pub trait ConstContentFormat: private::Sealed {
52 #[allow(private_interfaces)]
54 fn content_format() -> ContentFormat;
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
62pub struct Bytes<C: ConstContentFormat> {
63 inner: Vec<u8>,
64 _marker: std::marker::PhantomData<C>,
65}
66
67impl<C: ConstContentFormat> From<Vec<u8>> for Bytes<C> {
68 fn from(inner: Vec<u8>) -> Self {
69 Self {
70 inner,
71 _marker: std::marker::PhantomData,
72 }
73 }
74}
75
76impl<C: ConstContentFormat> From<&[u8]> for Bytes<C> {
77 fn from(inner: &[u8]) -> Self {
78 Self::from(inner.to_vec())
79 }
80}
81
82impl<C: ConstContentFormat + FromB64ContentFormat> From<&B64> for Bytes<C> {
83 fn from(val: &B64) -> Self {
84 Self::from(val.as_bytes())
85 }
86}
87
88impl<C: ConstContentFormat + FromB64ContentFormat> From<Bytes<C>> for B64 {
89 fn from(val: Bytes<C>) -> Self {
90 B64::from(val.as_ref())
91 }
92}
93
94impl<C: ConstContentFormat> AsRef<[u8]> for Bytes<C> {
95 fn as_ref(&self) -> &[u8] {
96 &self.inner
97 }
98}
99
100impl<C: ConstContentFormat> Bytes<C> {
101 pub fn to_vec(&self) -> Vec<u8> {
103 self.inner.clone()
104 }
105}
106
107#[derive(PartialEq, Eq, Clone, Debug)]
109pub(crate) struct Utf8ContentFormat;
110impl private::Sealed for Utf8ContentFormat {}
111impl ConstContentFormat for Utf8ContentFormat {
112 fn content_format() -> ContentFormat {
113 ContentFormat::Utf8
114 }
115}
116pub(crate) type Utf8Bytes = Bytes<Utf8ContentFormat>;
119
120#[derive(PartialEq, Eq, Clone, Debug)]
122pub struct OctetStreamContentFormat;
123impl private::Sealed for OctetStreamContentFormat {}
124impl ConstContentFormat for OctetStreamContentFormat {
125 #[allow(private_interfaces)]
126 fn content_format() -> ContentFormat {
127 ContentFormat::OctetStream
128 }
129}
130pub type OctetStreamBytes = Bytes<OctetStreamContentFormat>;
133
134#[derive(PartialEq, Eq, Clone, Debug)]
136pub struct Pkcs8PrivateKeyDerContentFormat;
137impl private::Sealed for Pkcs8PrivateKeyDerContentFormat {}
138impl ConstContentFormat for Pkcs8PrivateKeyDerContentFormat {
139 #[allow(private_interfaces)]
140 fn content_format() -> ContentFormat {
141 ContentFormat::Pkcs8PrivateKey
142 }
143}
144pub type Pkcs8PrivateKeyBytes = Bytes<Pkcs8PrivateKeyDerContentFormat>;
147
148#[derive(PartialEq, Eq, Clone, Debug)]
150pub struct SpkiPublicKeyDerContentFormat;
151impl private::Sealed for SpkiPublicKeyDerContentFormat {}
152impl ConstContentFormat for SpkiPublicKeyDerContentFormat {
153 #[allow(private_interfaces)]
154 fn content_format() -> ContentFormat {
155 ContentFormat::SPKIPublicKeyDer
156 }
157}
158impl FromB64ContentFormat for SpkiPublicKeyDerContentFormat {}
159pub type SpkiPublicKeyBytes = Bytes<SpkiPublicKeyDerContentFormat>;
162
163pub trait CoseContentFormat {}
165
166pub trait FromB64ContentFormat {}
168
169#[derive(PartialEq, Eq, Clone, Debug)]
171pub struct CoseKeyContentFormat;
172impl private::Sealed for CoseKeyContentFormat {}
173impl ConstContentFormat for CoseKeyContentFormat {
174 #[allow(private_interfaces)]
175 fn content_format() -> ContentFormat {
176 ContentFormat::CoseKey
177 }
178}
179impl CoseContentFormat for CoseKeyContentFormat {}
180impl FromB64ContentFormat for CoseKeyContentFormat {}
181pub type CoseKeyBytes = Bytes<CoseKeyContentFormat>;
184
185#[derive(PartialEq, Eq, Clone, Debug)]
187pub struct BitwardenLegacyKeyContentFormat;
188impl private::Sealed for BitwardenLegacyKeyContentFormat {}
189impl ConstContentFormat for BitwardenLegacyKeyContentFormat {
190 #[allow(private_interfaces)]
191 fn content_format() -> ContentFormat {
192 ContentFormat::BitwardenLegacyKey
193 }
194}
195impl FromB64ContentFormat for BitwardenLegacyKeyContentFormat {}
196pub type BitwardenLegacyKeyBytes = Bytes<BitwardenLegacyKeyContentFormat>;
200
201#[derive(PartialEq, Eq, Clone, Debug)]
203pub struct CoseSign1ContentFormat;
204impl private::Sealed for CoseSign1ContentFormat {}
205impl ConstContentFormat for CoseSign1ContentFormat {
206 #[allow(private_interfaces)]
207 fn content_format() -> ContentFormat {
208 ContentFormat::CoseSign1
209 }
210}
211impl CoseContentFormat for CoseSign1ContentFormat {}
212impl FromB64ContentFormat for CoseSign1ContentFormat {}
213pub type CoseSign1Bytes = Bytes<CoseSign1ContentFormat>;
216
217#[derive(PartialEq, Eq, Clone, Debug)]
219pub struct CborContentFormat;
220impl private::Sealed for CborContentFormat {}
221impl ConstContentFormat for CborContentFormat {
222 #[allow(private_interfaces)]
223 fn content_format() -> ContentFormat {
224 ContentFormat::Cbor
225 }
226}
227pub type CborBytes = Bytes<CborContentFormat>;
230
231#[derive(PartialEq, Eq, Clone, Debug)]
233pub struct CoseEncrypt0ContentFormat;
234impl private::Sealed for CoseEncrypt0ContentFormat {}
235impl ConstContentFormat for CoseEncrypt0ContentFormat {
236 #[allow(private_interfaces)]
237 fn content_format() -> ContentFormat {
238 ContentFormat::CoseEncrypt0
239 }
240}
241pub type CoseEncrypt0Bytes = Bytes<CoseEncrypt0ContentFormat>;
244
245impl<Ids: KeyIds, T: ConstContentFormat> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString>
246 for Bytes<T>
247{
248 fn encrypt(
249 &self,
250 ctx: &mut KeyStoreContext<Ids>,
251 key: Ids::Symmetric,
252 ) -> Result<EncString, CryptoError> {
253 self.inner.encrypt(ctx, key, T::content_format())
254 }
255}
256
257impl<T: ConstContentFormat> KeyEncryptable<SymmetricCryptoKey, EncString> for &Bytes<T> {
258 fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<EncString, CryptoError> {
259 self.as_ref().encrypt_with_key(key, T::content_format())
260 }
261}
262
263impl From<String> for Bytes<Utf8ContentFormat> {
264 fn from(val: String) -> Self {
265 Bytes::from(val.into_bytes())
266 }
267}
268
269impl From<&str> for Bytes<Utf8ContentFormat> {
270 fn from(val: &str) -> Self {
271 Bytes::from(val.as_bytes().to_vec())
272 }
273}