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